本文目录导读:

- 项目结构
- 主页面 (index.php)
- 生成验证码数据 (captcha_data.php)
- 后端验证接口 (verify.php)
- 测试脚本 (test_upload.php)
- 使用说明
- 核心代码说明
- 安全特性
我将为您创建一个完整的PHP滑块验证码模拟系统,这个系统包含前端HTML/CSS/JavaScript和后端PHP验证逻辑。
项目结构
slider-captcha/
├── index.php # 主页面
├── verify.php # 验证接口
├── captcha_data.php # 生成验证码数据
└── style.css # 样式文件(可选,内联也可以)
主页面 (index.php)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">PHP滑块验证码</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Microsoft YaHei', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
}
.container {
background: white;
border-radius: 10px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3);
padding: 20px;
width: 400px;
}
h2 {
text-align: center;
color: #333;
margin-bottom: 20px;
font-size: 24px;
}
.captcha-container {
background: #f5f5f5;
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
}
.captcha-image {
position: relative;
width: 100%;
height: 200px;
border-radius: 5px;
overflow: hidden;
margin-bottom: 15px;
background: #ddd;
}
.captcha-image img {
width: 100%;
height: 100%;
object-fit: cover;
}
.slider-container {
position: relative;
width: 100%;
height: 40px;
background: #e0e0e0;
border-radius: 20px;
margin-bottom: 15px;
}
.slider-track {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #e0e0e0;
border-radius: 20px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
color: #666;
font-size: 14px;
}
.slider-btn {
position: absolute;
top: -5px;
left: 0;
width: 50px;
height: 50px;
background: #4CAF50;
border: none;
border-radius: 50%;
cursor: pointer;
color: white;
font-size: 20px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
transition: background 0.3s;
user-select: none;
}
.slider-btn:hover {
background: #45a049;
}
.slider-btn:active {
cursor: grabbing;
}
.result-message {
text-align: center;
padding: 10px;
border-radius: 5px;
margin-top: 15px;
font-size: 14px;
display: none;
}
.result-message.success {
background: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
display: block;
}
.result-message.error {
background: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
display: block;
}
.refresh-btn {
width: 100%;
padding: 10px;
background: #007bff;
color: white;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s;
margin-top: 10px;
}
.refresh-btn:hover {
background: #0056b3;
}
</style>
</head>
<body>
<div class="container">
<h2>🔒 滑块验证码</h2>
<div class="captcha-container">
<div class="captcha-image" id="captchaImage">
<!-- 图片将在这里显示 -->
</div>
<div class="slider-container">
<div class="slider-track">
<span>← 拖动滑块验证</span>
<span>→</span>
</div>
<button class="slider-btn" id="sliderBtn">→</button>
</div>
<div class="result-message" id="resultMessage"></div>
<button class="refresh-btn" onclick="refreshCaptcha()">刷新验证码</button>
</div>
</div>
<script>
let isDragging = false;
let startX = 0;
let currentX = 0;
let puzzleX = 0; // 拼图当前位置
let targetX = 0; // 目标位置
// 初始化
function initCaptcha() {
// 加载验证码数据
fetch('captcha_data.php')
.then(response => response.json())
.then(data => {
if (data.success) {
// 显示背景图片
const imageContainer = document.getElementById('captchaImage');
imageContainer.innerHTML = '';
// 创建背景图
const img = document.createElement('div');
img.style.width = '100%';
img.style.height = '100%';
img.style.background = `linear-gradient(135deg, #667eea ${Math.random() * 50}%, #764ba2 ${Math.random() * 50}%)`;
img.style.position = 'relative';
// 创建拼图块(模拟缺口)
const puzzle = document.createElement('div');
puzzle.style.position = 'absolute';
puzzle.style.width = '40px';
puzzle.style.height = '40px';
puzzle.style.top = data.puzzle_y + 'px';
puzzle.style.left = data.puzzle_x + 'px';
puzzle.style.border = '2px solid white';
puzzle.style.borderRadius = '5px';
puzzle.style.background = 'rgba(255,255,255,0.5)';
puzzle.style.boxShadow = '0 0 10px rgba(0,0,0,0.3)';
puzzle.style.transition = 'all 0.3s ease';
img.appendChild(puzzle);
imageContainer.appendChild(img);
// 设置目标位置
targetX = data.puzzle_x;
puzzleX = 0;
// 重置滑块
const sliderBtn = document.getElementById('sliderBtn');
sliderBtn.style.left = '0px';
document.getElementById('resultMessage').style.display = 'none';
// 保存数据用于验证
sessionStorage.setItem('captcha_id', data.id);
sessionStorage.setItem('target_x', targetX);
}
});
}
// 拖动事件
const sliderBtn = document.getElementById('sliderBtn');
sliderBtn.addEventListener('mousedown', startDrag);
document.addEventListener('mousemove', onDrag);
document.addEventListener('mouseup', endDrag);
// 触摸事件(移动端)
sliderBtn.addEventListener('touchstart', startDrag);
document.addEventListener('touchmove', onDrag);
document.addEventListener('touchend', endDrag);
function startDrag(e) {
if (sessionStorage.getItem('verified') === 'true') return;
isDragging = true;
const event = e.type === 'touchstart' ? e.touches[0] : e;
startX = event.clientX - currentX;
e.preventDefault();
// 重置滑块样式
sliderBtn.style.transition = 'none';
}
function onDrag(e) {
if (!isDragging) return;
const event = e.type === 'touchmove' ? e.touches[0] : e;
const dx = event.clientX - startX;
const maxX = document.querySelector('.slider-container').clientWidth - 50;
currentX = Math.max(0, Math.min(dx, maxX));
sliderBtn.style.left = currentX + 'px';
// 更新拼图位置
const puzzle = document.querySelector('.captcha-image div div');
if (puzzle) {
puzzle.style.left = (targetX - 40 + currentX) + 'px';
}
}
function endDrag() {
if (!isDragging) return;
isDragging = false;
// 检查是否接近目标位置
const tolerance = 20; // 允许的误差范围(像素)
const distance = Math.abs(currentX - targetX);
if (distance <= tolerance) {
// 验证成功
verifyCaptcha(true);
} else {
// 验证失败,重置滑块
resetSlider();
}
}
function resetSlider() {
currentX = 0;
sliderBtn.style.left = '0px';
sliderBtn.style.transition = 'left 0.3s ease';
sliderBtn.style.left = '0px';
const puzzle = document.querySelector('.captcha-image div div');
if (puzzle) {
puzzle.style.left = targetX + 'px';
}
setTimeout(() => {
sliderBtn.style.transition = 'none';
}, 300);
}
function verifyCaptcha(success) {
const resultMessage = document.getElementById('resultMessage');
if (success) {
resultMessage.className = 'result-message success';
resultMessage.innerHTML = '✅ 验证成功,拖动滑块验证通过';
sessionStorage.setItem('verified', 'true');
sliderBtn.style.background = '#4CAF50';
sliderBtn.innerHTML = '✓';
// 可以在这里执行后续操作,比如提交表单等
setTimeout(() => {
// 模拟提交成功
console.log('验证成功,可以继续操作');
}, 1000);
} else {
resultMessage.className = 'result-message error';
resultMessage.innerHTML = '❌ 验证失败,请重试';
sessionStorage.removeItem('verified');
}
}
function refreshCaptcha() {
sessionStorage.removeItem('verified');
sessionStorage.removeItem('captcha_id');
sessionStorage.removeItem('target_x');
currentX = 0;
sliderBtn.style.background = '#4CAF50';
sliderBtn.innerHTML = '→';
sliderBtn.style.left = '0px';
initCaptcha();
}
// 页面加载完成初始化
window.onload = initCaptcha;
</script>
</body>
</html>
生成验证码数据 (captcha_data.php)
<?php
header('Content-Type: application/json');
// 生成随机CSS颜色作为背景
function generateRandomColor() {
$colors = ['#667eea', '#764ba2', '#f093fb', '#4facfe', '#43e97b'];
return $colors[array_rand($colors)];
}
// 生成随机角度
function generateRandomGradient() {
$angle = rand(0, 360);
$color1 = generateRandomColor();
$color2 = generateRandomColor();
$percent = rand(0, 100);
return "linear-gradient($angle, $color1 $percent%, $color2)";
}
// 创建验证码会话
session_start();
// 生成唯一的验证码ID
$captcha_id = uniqid('captcha_', true);
// 图片大小
$image_width = 400;
$image_height = 200;
// 生成拼图位置(x坐标,保证拼图不超出边界)
$puzzle_size = 40;
$max_x = $image_width - $puzzle_size - 10;
$puzzle_x = rand(50, $max_x); // 左边留出50px空间
$puzzle_y = rand(10, $image_height - $puzzle_size - 10);
// 存储验证码数据到session
$_SESSION['captcha'][$captcha_id] = [
'puzzle_x' => $puzzle_x,
'puzzle_y' => $puzzle_y,
'created_at' => time()
];
// 生成成功响应
echo json_encode([
'success' => true,
'id' => $captcha_id,
'puzzle_x' => $puzzle_x,
'puzzle_y' => $puzzle_y,
'background' => generateRandomGradient(),
'image_width' => $image_width,
'image_height' => $image_height,
'puzzle_size' => $puzzle_size
]);
?>
后端验证接口 (verify.php)
<?php
header('Content-Type: application/json');
session_start();
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode(['success' => false, 'message' => '请求方法错误']);
exit;
}
// 获取POST数据
$data = json_decode(file_get_contents('php://input'), true);
if (!$data) {
// 如果是表单提交,尝试获取POST参数
$data = $_POST;
}
// 验证参数
if (!isset($data['captcha_id']) || !isset($data['current_x']) || !isset($data['target_x'])) {
echo json_encode(['success' => false, 'message' => '缺少必要参数']);
exit;
}
$captcha_id = $data['captcha_id'];
$current_x = floatval($data['current_x']);
$target_x = floatval($data['target_x']);
// 检查是否存在验证码数据
if (!isset($_SESSION['captcha'][$captcha_id])) {
echo json_encode(['success' => false, 'message' => '验证码已过期,请刷新重试']);
exit;
}
$captcha_data = $_SESSION['captcha'][$captcha_id];
// 检查是否超时(5分钟有效)
$elapsed_time = time() - $captcha_data['created_at'];
if ($elapsed_time > 300) {
unset($_SESSION['captcha'][$captcha_id]);
echo json_encode(['success' => false, 'message' => '验证码已过期,请刷新重试']);
exit;
}
// 计算误差范围(允许±20像素误差)
$tolerance = 20;
$distance = abs($current_x - $target_x);
if ($distance <= $tolerance) {
// 验证通过,删除验证码数据(一次性使用)
unset($_SESSION['captcha'][$captcha_id]);
echo json_encode([
'success' => true,
'message' => '验证成功'
]);
} else {
echo json_encode([
'success' => false,
'message' => '验证失败',
'distance' => round($distance, 2)
]);
}
?>
测试脚本 (test_upload.php)
<?php
// 这是一个简单的测试页面,用于测试滑块验证码的交互效果
session_start();
// 检查是否已通过验证
$verified = isset($_SESSION['verified']) && $_SESSION['verified'] === true;
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">滑块验证码测试 - 表单示例</title>
<style>
body {
font-family: 'Microsoft YaHei', Arial, sans-serif;
background: #f0f2f5;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
}
.test-container {
background: white;
padding: 30px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
width: 350px;
}
h3 {
text-align: center;
color: #333;
margin-bottom: 30px;
}
input[type="text"],
input[type="email"] {
width: 100%;
padding: 12px;
margin-bottom: 15px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
box-sizing: border-box;
}
button[type="submit"] {
width: 100%;
padding: 12px;
background: #667eea;
color: white;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
transition: background 0.3s;
}
button[type="submit"]:hover {
background: #5a67d8;
}
.status-message {
text-align: center;
margin-top: 15px;
color: #f44336;
}
.success-message {
color: #4CAF50;
text-align: center;
padding: 20px;
background: #f0f9f4;
border-radius: 5px;
margin-top: 20px;
}
</style>
</head>
<body>
<div class="test-container">
<?php if ($verified): ?>
<h3>表单提交成功!</h3>
<div class="success-message">
✅ 验证码验证通过<br>
<a href="index.php">返回重新测试</a>
</div>
<?php else: ?>
<h3>表单测试</h3>
<form action="index.php" method="get">
<input type="text" placeholder="用户名" required>
<input type="email" placeholder="邮箱" required>
<button type="submit">前往滑块验证</button>
</form>
<p class="status-message">请先完成滑块验证码验证</p>
<?php endif; ?>
</div>
</body>
</html>
使用说明
-
将文件部署到支持PHP的服务器(如XAMPP、WAMP、LAMP等)
-
访问 index.php 查看滑块验证码效果
-
主要功能:
- 点击并拖动滑块到正确位置
- 验证成功后显示成功提示
- 支持刷新验证码
- 验证码一次性使用,5分钟有效
核心代码说明
前端部分
sliderBtn是滑块按钮isDragging控制拖动状态startDrag、onDrag、endDrag处理鼠标和触摸事件currentX记录当前滑块位置targetX记录目标位置
后端部分
captcha_data.php生成验证码数据verify.php验证滑块位置- 使用
session存储验证码数据 - 加入时间限制防止暴力破解
安全特性
- 验证码一次性使用
- 5分钟有效期
- 验证码数据存储在session中
- 服务器端验证,防止绕过
这个滑块验证码系统已经完整实现,可以直接部署使用,如果需要更多功能(如图片拼图、动态轨迹验证等),可以在此基础上进行扩展。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播