作用:区分人和机器。
我们经常看到的以几个汉字或者数字、字母组成的字符串,其实在客户端展示的是一张图片。因为如果使用字符串,是很容易被机器提取识别的。单独的图片上只有几个字符的话对于一些机器来讲也是很容易比对识别的,因此就需要一些干扰元素,我们最常见的干扰元素就是一些点和线。在客户端识别到字符,并输入提交的时候,服务器需要判断用户提交验证码的正确性。需要跟什么比对呢?需要跟验证码图片上的文字做比对,因此就需要对这个生成验证码的字符串进行保存。
最简单的验证码应该具有以下性质:
1、是一张图片
2、有可验证的信息
3、具有干扰元素
4、可验证正确性(服务器验证信息存储)
5、随机性
php实现:
php是靠GD库来实现对图片的操作。
1、生成图片
/*生成一张真彩色图片,大小为100px x 30px*/
$img = imagecreatetruecolor(100, 30);//生成的真彩色图片默认颜色为黑色
/*指定一种可用于图片的颜色*/
$bg = imagecolorallocate($img, 255, 255, 255);
/*使用之前指定的颜色为图片填充颜色,从图片的左上角开始填充,也就是坐标的(0,0)点*/
imagefill($img, 0, 0, $bg);
到这里我们就生成了一张可用于“创作”的图片,个人认为在这里称为画布更为确切。
2、制作可验证的信息
我们使用函数,将字符串画在画布上,可以一次性绘出,但就不能均匀分布了,缺少美观。因此应该采用循环的方式将他们依次画上去。
绘制字符串函数语法:
bool imagestring ( resource $image , int $font , int $x , int $y , string $s , int $col )
- resource $image 画布
- $font 字体尺寸
- $x 画布x坐标
- $y 画布y坐标
- $s 字符
- $col 绘制的颜色
/*在这里,我们绘制验证信息*/
for($i=0;$i<4;$i++){
$font_size = 15;
$xpos = $i*(100/4) + mt_rand(5,10);
$ypos = mt_rand(5,10);
$strcolor = imagecolorallocate($img, mt_rand(0,120), mt_rand(0,120),mt_rand(0,120)); //生成随机颜色
$str = ;//生成随机的字符
imagestring($image, $font_size, $xpos, $ypos, $str, $strcolor);
}
3、生成干扰元素
这里只制作随机点和随机线,还是采用循环的方式。
点绘制函数语法
bool imagesetpixel ( resource $image , int $x , int $y , int $color )
- $image 画布
- $x 像素点的x坐标
- $y 像素点的y坐标
- $color 像素点的颜色
/*在这里,我们绘制干扰像素点*/
for($i=0;$i<200;$i++){
$xpos = mt_rand(0, 99);
$ypos = mt_rand(0, 29);
$pointcolor = imagecolorallocate($img, mt_rand(50, 200), mt_rand(50, 200),mt_rand(50, 200)); //生成随机颜色
imagesetcolor($img, $xpos, $ypos, $pointcolor);
}
线绘制函数语法
bool imageline ( resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color )
- $x1 线段起点x坐标
- $y1线段起点y坐标
- $x2线段终点x坐标
- $y2线段终点y坐标
/*在这里,我们绘制干扰线*/
for($i=0;$i<4;$i++){
$x1pos = mt_rand(0, 99);
$y1pos = mt_rand(0, 29);
$x2pos = mt_rand(0, 99);
$y2pos = mt_rand(0, 29);
$linetcolor = imagecolorallocate($img, mt_rand(80,200), mt_rand(80,200),mt_rand(80,200)); //生成随机颜色
imagesetcolor($img, $x1pos, $y1pos, $x2pos, $y2pos, $linecolor);
}
4、可验证性–存储
采用session来存储信息,首先就要开启session,必须要在代码最顶部。
session_start(); //在代码最顶部开启
//....
$captchacode = '';//声明一个字符串,用于存储字符串
/*在这里,我们绘制验证信息*/
for($i=0;$i<4;$i++){
//....
$str = ;//生成随机的字符
$captchacode .= $str; //拼接字符串
}
$_SESSION['authcode'] = $catchacode; //将验证码保存在服务器
5、随机性
随机生成数字和英文字符串
$str_db = 'abcdefghijklmnopqrstuvwxyz0123456789';
$str = substr($str_db, mt_rand(0,strlen($str_db)), 1);
随机生成中文字符串
$str_db = '这是一段中文测试代码';
$str = mb_substr($str_db, mt_rand(0,mb_strlen($str_db,'utf-8')), 1, 'utf-8');
6、通过表单提交验证
if(isset($_GET['authcode']){ //判断是否存在
session_start(); //因为需要读取session,因此也需要将此打开.表示启动新会话或者重用现有会话
$authcode = $_GET['authcode']; //表单设置为get方式,因此这个使用$_GET
if(strtolower($authcode) == $_SESSION['authcode']){ //这里是将用户输入全部转为小写。
echo '输入成功';
}else {
echo '输入错误';
}
exit();
}
7、动态生成验证码图片
在实际生产中,验证由于随机性,很可能导致本身用户也无法识别的情况,这时候就需要验证码能够更换,当用户点击按钮或者验证码图片时。
在生成验证码图片的时候,需要给每个图片一个随机的id
form表单:
form method="post" action="./form.php">
<p class="captcha"><input type="text" name="authcode" id="captcha_input"><a href="javascript:void(0)" id="change1"><img src="./captcha.php?r=<?php echo rand()?>" alt="" id="captcha-img1"/></a></p> <!--这里的rand()保证了随机的图片,更好的用于下次更换。相当于每次访问的是不同的网页,当然会生成不同的图片-->
<p><input type="submit" name="" value="提交" id="submit"></p>
</form>
为验证码图片添加点击事件
window.onload = function(){
var el1 = document.getElementById('change1');
el1.onclick = function(){
var img = document.getElementById('captcha-img1');
img.src = './captcha.php?r=' + Math.random(); //必须保证每次生成的不一样
}
}
前端
作为前端,还是初级。php也刚涉猎,那么前端如何编写纯前端的验证代码呢?
html:
<form method="post" > <!--form在这里是可有可无的-->
<p class="captcha"><input type="text" name="authcode" id="captcha_input"><a href="javascript:void(0)" id="change1"><img src="./captcha.php" alt="" id="captcha-img1"/></a></p>
<p><input type="submit" name="" value="提交" id="submit"></p>
</form>
js:
$(document).ready(function(){
el = document.getElementById('captcha-img1');
/**为验证码图片添加点击事件,点击时更换验证码*/
el.onclick = function(){
el.src = './captcha.php?r='+ Math.random();
}
/**为提交按钮添加点击事件,点击时发送ajax请求*/
$('#submit').on('click',function(){
var code = $('#captcha_input').val();
$.ajax({
url: './form.index.php', //处理请求的php文件
type: 'POST', //提交方式
dataType: 'text', //返回信息的类型
data: {authcode: code}, //提交的信息
success: function(result){
console.log(result); //此处输出的result是php代码中echo的部分
}
})
.done(function() {
console.log("success");
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
});
});
});
php:
<?php
if(isset($_POST['authcode'])) {
session_start(); //开启会话
if(strtolower($_POST['authcode']) == $_SESSION['authcode']){ //验证
echo '输入正确';
}else {
echo '输入错误';
}
exit();
}
?>
WHY
为什么我们可以通过ajax提交信息到服务器?
我们提交数据的操作也被称作http请求,ajax有两种http请求–GET请求和POST请求。既然都是http请求,那么,这个为什么的答案也就在http请求中。
HTTP请求
服务器的处理代码在处理好之后又是怎么样将信息反馈给客户端的?
发送方式,是以http响应的方式发送给客户端。