写这篇文章的初衷,纯粹是为了cavans练习。实际工作中不建议使用前端生成的图片验证码;前端使用验证码的初衷是为了防止用户错误地请求接口,同时也是为了避免别有用心的人频繁请求接口。攻击;所以,如果后台能提供验证码接口,尽量使用后台提供的接口,拖拽验证;但这并不妨碍我们学习它。图片验证码的主要实现方式是cavans。我们可以借此机会了解cavans;需求分析还记得上次看到图片验证码是什么时候吗?你还记得一张图片验证码是由哪些元素组成的吗?我只总结了两点:字符串干扰元素和字符串干扰元素也有多个属性比如:相对偏移字体字体颜色字体大小阴影效果字符串长度和字符串干扰元素是图片携带的,图片还有宽度,高度和背景色,一个完整的需求,需要一些交互,比如:图片生成的刷新验证码的对比和实现.接下来我们进行一个简单的实现。通过上面的分析,我们大致知道我们需要属性,所以接下来我们可以创建classVerification{constructor(length=6,style={width:200,height:30,hasDot:true,hasLine:true}){this.code=null//随机码字符串this.path=null//生成图片地址this.length=length//验证码长度this.width=style.width//图片宽度this.height=style.height//图片高度this.hasDot=样式。hasDot//是否有干扰点this.hasLine=style.hasLine//是否有干扰线this.create()}create(){//创建随机字符串constchars='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'constmaxLength=字符。lengthletcode=''for(leti=0;i{returnMath.floor(Math.random()*(max-min)+min);}//获取随机颜色constgetRandomColor=(min,max,a=1)=>{letr=getRandomNum(min,max);让g=getRandomNum(min,max);让b=getRandomNum(min,max);返回`rgba(${r},${g},${b},${a})`;}constcanvas=document.createElement('canvas')canvas.width=this.widthcanvas.height=this.heightconstctx=canvas.getContext('2d')ctx.textBaseline="middle";//设置方法ctx.fillStyle=getRandomColor(180,240);//图片背景颜色设置,尝试设置设置背景为浅色,文字为深色,方便阅读ctx.fillRect(0,0,this.width,this.height);//背景色绘制[...this.code].forEach((char,i)=>{ctx.font=getRandomNum(this.height/2,this.height)+'pxpingfangsc';//随机生成字体大小ctx.fillStyle=getRandomColor(80,150)//随机生成字体颜色ctx.shadowOffsetX=getRandomNum(-5,5);//文字阴影X轴偏移量ctx.shadowOffsetY=getRandomNum(-5,5);//文字阴影Y轴偏移量ctx.shadowColor=getRandomColor(80,150,0.4);//文字阴影颜色//文字渲染X偏移计算/**用图片的宽度除以代码的长度得到文字在图片中的偏移量,避免重叠**/letx=this.width/this.length*i;//因为文字大小大于等于this.height/2且小于等于this.height,所以设置this.height/2显示全部lety=this.height/2;//文字旋转偏移量letdeg=getRandomNum(-10,10);//设置文本偏移量ctx.translate(x,y);//设置文字旋转ctx.rotate(deg*Math.PI/180);//文字绘制ctx.fillText(字符,0,0);//画布旋转回正ctx.rotate(-deg*Math.PI/180);//画布偏移量回到正值ctx.translate(-x,-y);//是否连线if(this.hasLine){ctx.strokeStyle=getRandomColor(60,160);//随机设置线条颜色ctx.beginPath();//起始路径ctx.moveTo(getRandomNum(0,this.width),getRandomNum(0,this.height));//线起点ctx.lineTo(getRandomNum(0,this.width),getRandomNum(0,this.height));//线终点ctx.stroke();//画线}//是不是有点if(this.hasDot){ctx.fillStyle=getRandomColor(0,255);//随机设置点颜色ctx.beginPath();//起始路径ctx.arc(getRandomNum(0,this.width),getRandomNum(0,this.height),1,0,2*Math.PI);//点设置ctx.fill();//点画}})this.path=canvas.toDataURL("image/png")}//验证输入的验证码是否等于生成的equal(code){//转为英文大写进行比较returncode.toUpperCase()===this.code.toUpperCase()}}constv=newVerification()document.getElementById('picture').setAttribute("src",v.path)复制代码