JS 实现图片验证码(加强版)

原创 2023-07-22 05:33
文章的分类 代码乐园

前言

2023-07-21T21:39:18.png
老早就想搞个图片验证码了,虽然没有目前来讲垃圾评论但是还是想搞,之前也看到好多博友被刷垃圾评论。于是白天懒得搞,一到晚上就精神焕发,再于是就去网上查找了一番,但是发现,如果验证码 input 被删除了,就不用输验证码也能评论,于是又花了一会时间,修改了一下,删除了就不能提交了,最后大功告成!!!

JS

 !(function(window, document) {
    function GVerify(options) { //创建一个图形验证码对象,接收options对象为参数
        this.options = { //默认options参数值
            id: "comment-form", //容器Id
            canvasId: "verifyCanvas", //canvas的ID
            width: "100", //默认canvas宽度
            height: "38", //默认canvas高度
            type: "blend", //图形验证码默认类型blend:数字字母混合类型、number:纯数字、letter:纯字母
            code: ""
        }
        
        if(Object.prototype.toString.call(options) == "[object Object]"){//判断传入参数类型
            for(var i in options) { //根据传入的参数,修改默认参数值
                this.options[i] = options[i];
            }
        }else{
            this.options.id = options;
        }
        
        this.options.numArr = "1,2,3,4,5,6,7,8,9".split(",");
        this.options.letterArr = getAllLetter();

        this._init();
        this.refresh();
    }

    GVerify.prototype = {
        /**版本号**/
        version: '1.0.0',
        
        /**初始化方法**/
        _init: function() {
            var con = document.getElementById(this.options.id);
            var canvas = document.createElement("canvas");
            this.options.width = con.offsetWidth > 0 ? con.offsetWidth : "100";
            this.options.height = con.offsetHeight > 0 ? con.offsetHeight : "38";
            canvas.id = this.options.canvasId;
            canvas.width = this.options.width;
            canvas.height = this.options.height;
            canvas.style.cursor = "pointer";
            canvas.innerHTML = "您的浏览器版本不支持canvas";
            con.appendChild(canvas);
            var parent = this;
            canvas.onclick = function(){
                parent.refresh();
            };
        },
        
        /**生成验证码**/
        refresh: function() {
            this.options.code = "";
            var canvas = document.getElementById(this.options.canvasId);
            if(canvas.getContext) {
                var ctx = canvas.getContext('2d');
            }else{
                return;
            }
            
            ctx.textBaseline = "middle";

            ctx.fillStyle = randomColor(180, 240);
            ctx.fillRect(0, 0, this.options.width, this.options.height);

            if(this.options.type == "blend") { //判断验证码类型
                var txtArr = this.options.numArr.concat(this.options.letterArr);
            } else if(this.options.type == "number") {
                var txtArr = this.options.numArr;
            } else {
                var txtArr = this.options.letterArr;
            }

            for(var i = 1; i <= 4; i++) {
                var txt = txtArr[randomNum(0, txtArr.length)];
                this.options.code += txt;
                ctx.font = randomNum(this.options.height/2, this.options.height) + 'px SimHei'; //随机生成字体大小
                ctx.fillStyle = randomColor(50, 160); //随机生成字体颜色        
                ctx.shadowOffsetX = randomNum(-3, 3);
                ctx.shadowOffsetY = randomNum(-3, 3);
                ctx.shadowBlur = randomNum(-3, 3);
                ctx.shadowColor = "rgba(0, 0, 0, 0.3)";
                var x = this.options.width / 5 * i;
                var y = this.options.height / 2;
                var deg = randomNum(-30, 30);
                /**设置旋转角度和坐标原点**/
                ctx.translate(x, y);
                ctx.rotate(deg * Math.PI / 180);
                ctx.fillText(txt, 0, 0);
                /**恢复旋转角度和坐标原点**/
                ctx.rotate(-deg * Math.PI / 180);
                ctx.translate(-x, -y);
            }
            /**绘制干扰线**/
            for(var i = 0; i < 4; i++) {
                ctx.strokeStyle = randomColor(40, 180);
                ctx.beginPath();
                ctx.moveTo(randomNum(0, this.options.width), randomNum(0, this.options.height));
                ctx.lineTo(randomNum(0, this.options.width), randomNum(0, this.options.height));
                ctx.stroke();
            }
            /**绘制干扰点**/
            for(var i = 0; i < this.options.width/4; i++) {
                ctx.fillStyle = randomColor(0, 255);
                ctx.beginPath();
                ctx.arc(randomNum(0, this.options.width), randomNum(0, this.options.height), 1, 0, 2 * Math.PI);
                ctx.fill();
            }
        },
        
        /**验证验证码**/
        validate: function(code){
            var code = code.toLowerCase();
            var v_code = this.options.code.toLowerCase();
            if(code == v_code){
                alert('运气不错呀,这么难都答对啦!')
                
                return true;
            }else{
                alert('运气不太好呀,重新输一下吧~~')
                document.getElementById("viewInpt").value="";
                // this.refresh(); 禁止自动刷新
                return false;
                
            }
        }
    }
    /**生成字母数组**/
    function getAllLetter() {
        var letterStr = "a,b,c,d,e,f,g,h,i,j,k,m,n,p,q,r,s,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,S,T,U,V,W,X,Y,Z";
        return letterStr.split(",");
    }
    /**生成一个随机数**/
    function randomNum(min, max) {
        return Math.floor(Math.random() * (max - min) + min);
    }
    /**生成一个随机色**/
    function randomColor(min, max) {
        var r = randomNum(min, max);
        var g = randomNum(min, max);
        var b = randomNum(min, max);
        return "rgb(" + r + "," + g + "," + b + ")";
    }
    window.GVerify = GVerify;
  })(window, document);

   var gVerify=new GVerify("view");//传入你要把验证码的图片生成的位置的id
    function yanzheng(){
      var str=$("#viewInpt").val()//获取输入框内容
      console.log(gVerify.validate(str))//验证输入的验证码是否正确
        }
        
        
 function validateCaptcha() {
    var input = document.getElementById("viewInpt").value;
  }
// 使用事件监听器来捕获表单提交事件
  var form = document.querySelector("form");
  form.addEventListener("submit", function (event) {
    // 阻止默认的表单提交行为
    event.preventDefault();

    // 执行您想要的功能
    validateCaptcha();

    // 如果验证成功,则手动提交表单
    if (validateCaptcha() == true) {
       alert('运气不太好呀,重新输一下吧~~')
    } else {
        form.submit();
      alert('稍等片刻 努力提交数据~~')
    }
  });

Html

   <input type="text"  id="viewInpt" onblur="yanzheng()"  placeholder="请输入图片验证码" required="required">

问答悬赏

然后问答模式修改成了问答悬赏再 PC 端的左侧显示,不然老是白嫖,感觉有点浪费别人时间,对问题也是会提高一些效率吧!

2023-07-21T21:38:05.png



THE END


分享
赞赏
精选留言 写留言
    1. 123 来自中国湖北省黄冈市团风县 访客 头像

      222

      2023年10月01日
    1. vian 来自河北省石家庄市电信 访客 头像

      你小子让我填验证码 表情

      2023年09月23日
    1. 小赵同学 来自湖北省襄阳市电信 访客 头像

      功能上确实可以阻挡一些 垃圾评论 但是 会给访客增加一些麻烦 有些访客看到图片验证码也许就不想评论了 有点棘手 或许可以考虑一下滑块验证(当然也是个人意见) 表情

      2023年07月31日
    1. 锟斤拷锟斤拷 来自陕西省西安市移动 访客 头像

      1 表情

      2023年07月25日