按照自己的思路写了一个拖动验证,不知道别人是不是这样写的,我觉得方法应该差不多。不废话,上代码。
<?php
require_once 'Check.php';
if($data = Check::create()){
$x = $data['x'];
$y = ($data['y'] - 5).'px';
$name = $data['name'];
session_start();//开启会话,保存验证信息
$_SESSION['x'] = $x;
$_SESSION['name'] = $name;
$_SESSION['check'] = false; //刷新本页面要重新验证。
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>demo7</title>
<style>
#body{
position: relative;
width: 470px;
height: 50px;
margin: 400px auto;
}
#checkingBody{
position: absolute;
width: 470px;
box-sizing: border-box;
padding: 10px 10px;
height: 160px;
background: #E8E8E8;
left: 0;
top:-170px;
display: none;
}
#checkingPack{
width: 100%;
height: 100%;
position: relative;
}
#checking{
width: 50px;
height: 50px;
position: absolute;
left:0;
top:<?php echo $y ?>;
border: 5px solid #00FFFF;
}
#sliderPack{
width: 440px;
height: 50px;
border: 1px solid darkgrey;
position: relative;
margin-left: 15px;
}
#slider{
width: 50px;
background: darkgrey;
height: 50px;
position: absolute;
}
#checkingPackImage{
width:100%;
height:100%;
}
#checkingImage{
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="body">
<div id="checkingBody">
<div id="checkingPack">
<img id="checkingPackImage" src="<?php echo 'check/'.$name.'A.jpg' ?>" alt="<?php echo $name.'A.jpg' ?>">
<div id="checking">
<img id="checkingImage" src="<?php echo 'check/'.$name.'B.jpg' ?>" alt="<?php echo $name.'B.jpg' ?>">
</div>
</div>
</div>
<div id="sliderPack">
<div id="slider"></div>
</div>
</div>
<script src="https://cdn.bootcss.com/jquery/3.4.0/jquery.min.js"></script>
<script>
$(function () {
let sliderPack = document.getElementById("sliderPack");
let slider = document.getElementById("slider");
let checking = document.getElementById("checking");
let checkingBody = document.getElementById("checkingBody");
let isSending = false;
let differenceX;
let isDown = false;
let isMove = false;
slider.onmousedown = function (e) {
differenceX = e.clientX - this.offsetLeft;
this.style.cursor = "move";
checkingBody.style.display = "block";
isDown = true;
};
sliderPack.onmousemove = function (e) {
if(!isDown || isSending){
return false;
}
isMove = true;
let newLeft = e.clientX - differenceX;
if(newLeft<0){
newLeft = 0;
}
if(newLeft>390){
newLeft = 390;
}
slider.style.left = newLeft + "px";
checking.style.left = newLeft + "px";
setInterval(function(){ //移动的时候,执行监听函数。
let x1 = slider.style.left; //记录x1
setTimeout(function () {
let x2 = slider.style.left; // 300毫秒后记录x2
if(x1===x2 && !isSending && isMove){ //如果x1 等于 x2 说明鼠标停留了
isSending = true; //提交标识开启,防止多次提交。
isMove = false; //移动标识改成false,这样做是为了让用户验证失败后要再次移动才发送验证。
$.ajax({
url:"demo8.php",
data:{
x:parseInt(slider.style.left)//把距离左边的距离去掉px 再发送
},
type:"get",
dataType:"json",
success:function (e) {
if(e.message==="SUCCESS"){
//验证成功
}else{
//验证失败
isSending = false;
}
},
error:function () {
isSending = false;
}
})
}
},300)
},500);
};
sliderPack.onmouseup = function () {
if(!isDown){
return false
}
isDown = false;
slider.style.cursor = "default";
};
sliderPack.onmouseleave = function () {
isDown = false;
slider.style.cursor = "default";
checkingBody.style.display = "none";
}
})
</script>
</body>
</html>
这里用了混编的方式,只是为了演示 。
<?php
class Check
{
static function create(){
//生成一个随机坐标,作为裁剪图片左上角的坐标。
$x = mt_rand(100,395); //最左的坐标设置成100,为了让裁剪位置尽量出现在右边的位置,好让用户滑动一定的距离。
$y = mt_rand(5,85);
$image = imagecreatefromjpeg('check.jpg'); //准备一张宽450 高140 的图片作为底片。
$newImage = imagecreatetruecolor(50,50); //创建一个空白的图片。
imagecopyresampled($newImage,$image,0,0,$x,$y,50,50,50,50); //把底片的一部分裁剪到空白的图片。
$gray = imagecolorallocate($image,156,156,156); //创建灰色的画笔。
imagefilledrectangle($image, $x, $y,$x+50,$y+50,$gray); //填充一个灰色的矩形并覆盖到裁剪的位置。
imagesetthickness($image,6); //设置画线的宽度,准备画一个粗边框的矩形在裁剪的位置,突出裁剪的位置。
$cyan = imagecolorallocate($image,0,255,255); //创建青色的画笔。
imagerectangle($image,$x-3,$y-3,$x+53,$y+53,$cyan); //画青色的矩形。
ini_set('date.timezone','Asia/Shanghai'); //设置时区。
$dateTime = new DateTime(); //创建一个DateTime对象,用来获取毫秒。
$name = date('Y').date('m').date('d').date('H').date('i').$dateTime->format('u').mt_rand(0,9);
//以时间加随机数的形式作为图片名字。
$path = 'check/'; //图片保存目录
imagejpeg($image,$path.$name.'A.jpg'); //保存图片,底片以大写字母A结尾。
imagejpeg($newImage,$path.$name.'B.jpg'); //保存图片,裁剪的图片以大写字母B结尾。
imagedestroy($newImage); //释放内存。
imagedestroy($image); //释放内存。
$data['x'] = $x;
$data['y'] = $y;
$data['name'] = $name;
//把坐标和名字赋值给数组。
return $data;//返回数组。
}
}
这个静态方法作用是创建验证用的图片。
<?php
$newX = $_GET['x'];
if(empty($newX)){
die(json_encode('')); //如果没接收到x,返回错误信息并结束脚本
}
/*
*
*
* 这里可以写限制访问次数的脚本,防止别人攻击这个接口。
*
*
*
*
*
*
*
*
*/
session_start(); //开启会话
$x = $_SESSION['x'];
if(empty($x)){
die(json_encode('')); //如果会话没有保存到x的信息,返回错误信息并结束脚本
}
if($newX > $x - 10 && $newX < $x +10){
$_SESSION['check'] = true; //如果用户发送的 x 在 会话里 保存的x 的一定范围内 则验证通过
$data['message'] = 'SUCCESS';
echo json_encode($data);//返回拖动验证成功标识
}else{
echo json_encode(''); //返回验证失败信息
/**
*
*
* 这里面可以写错误次数过多的脚本。
*
*
*
*
*
*
*/
}
验证坐标是否正确
<?php
session_start();
if($_SESSION['check']){
//拖动验证成功,执行验证用户信息
/*
*
*
* 验证用户信息。
*
*
*
*
*
*
*
*
*
*
*
*/
//
$_SESSION['check'] = false; //如果验证用户信息成功,则改成false,拖动验证成功一次只能登录一个用户
}
验证用户信息是否正确。
以上就是全部代码。