JavaScript编写带旋转+线条干扰的验证码脚本实例


Posted in Javascript onMay 30, 2016

基础版

从我们平时上网的经验来看,验证码一般是四位,由数字和字母组成。
那么接下来楼主将带领大家一步步用JavaScript做出一个验证码脚本!
先给出成品,方便大家理解:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
   <style>
    #securityCode{
      background-color: #008000;
      width:70px;
      height:30px;
      font-family: '楷体', serif;
      font-size: 20px;
      color:white;
    }
  </style>
  <script language="JavaScript" type="text/javascript">
   function createCode(){
      var code=new Array(0,1,2,3,4,5,6,7,8,9,
          'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
      var codeNumber;
      securityCode="";//全局变量,方便后续验证
      for(var i=0;i<4;i++){
        codeNumber=Math.floor(Math.random()*36);
        securityCode+=code[codeNumber];
      }
      document.getElementById("securityCode").value=securityCode;
    }
    function verify(){
      var enterCode=document.getElementById("enterCode").value;
      if(enterCode.toUpperCase()==securityCode){
        alert("输入正确,通过验证!");
      }
      else{
        enterCode.value="";
        createCode();
      }
    }
  </script>
    <title>Jizhen Tan</title>
</head>
<body onLoad="checkCookie()" >
   <input type="text" id="enterCode"><br/>
   <input type="button" id="securityCode"  onclick="createCode()">
   <a href="###" onclick="createCode()">看不清楚</a><br/>
   <input type="button" style="background-color: #0099FF; font-size: 20px;"value="验证" onclick="verify()">
</body>
</html>

1.既然是四位验证码,我们的思路就要打开一些了,首先我们需要一个数组来储存字母和数字。

var code=new Array(0,1,2,3,4,5,6,7,8,9,
          'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');

2.然后我们需要让它随机显示数组中的元素,这里我们建立一个codeNumber变量来随机显示的数字,但我们需要的是四位验证码,而现在数组中的元素都是单个的,怎么办呢?简单!我们再建立一个securityCode变量来储存数组中的元素不就得了。代码如下:

var codeNumber;
      securityCode="";//全局变量,方便后续验证
      for(var i=0;i<4;i++){
        codeNumber=Math.floor(Math.random()*36);
        securityCode+=code[codeNumber];
      }

可以看出此时securityNumber变量储存的就是一个四位随机验证码
3.好了,经过简单的两步,我们就得到了四位验证码。我们将它放在一个createCode函数中。

function createCode(){
      var code=new Array(0,1,2,3,4,5,6,7,8,9,
          'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
      var codeNumber;
      securityCode="";//全局变量,方便后续验证
      for(var i=0;i<4;i++){
        codeNumber=Math.floor(Math.random()*36);
        securityCode+=code[codeNumber];
      }
      document.getElementById("securityCode").value=securityCode;
    }

4.接下来我们创建一个验证机制:

function verify(){
      var enterCode=document.getElementById("enterCode").value;
      if(enterCode.toUpperCase()==securityCode){
        alert("输入正确,通过验证!");
      }
      else{
        enterCode.value="";
        createCode();
      }
    }

5.小小修饰下验证码:

<style>
    #securityCode{
      background-color: #008000;
      width:70px;
      height:30px;
      font-family: '楷体', serif;
      font-size: 20px;
      color:white;
    }
  </style>

进阶:进一步阻止机器人的高级技巧
接触的大部分项目中,验证码一直都是后台干的事,这两天正好有一个页面需要验证码,第时间想着后台实现,但突然转念一想大部分项目貌似对安全性要求不是很高,又要求有点阻止机器人的技巧,于是就用前端写了一个验证码。并利用CSS3的transform属性里的rotate设置旋转,再随机弄点干扰线,最后为了在所有DOM节点的上边加一层opacity=0的DIV,一个前端验证码就出来了。

JavaScript编写带旋转+线条干扰的验证码脚本实例

vCode代码:

(function(){
  var randstr = function(length){
    var key = {
 
      str : [
        'a','b','c','d','e','f','g','h','i','j','k','l','m',
        'o','p','q','r','s','t','x','u','v','y','z','w','n',
        '0','1','2','3','4','5','6','7','8','9'
      ],
 
      randint : function(n,m){
        var c = m-n+1;
        var num = Math.random() * c + n;
        return Math.floor(num);
      },
 
      randStr : function(){
        var _this = this;
        var leng = _this.str.length - 1;
        var randkey = _this.randint(0, leng);
        return _this.str[randkey];
      },
 
      create : function(len){
        var _this = this;
        var l = len || 10;
        var str = '';
 
        for(var i = 0 ; i<l ; i++){
          str += _this.randStr();
        }
 
        return str;
      }
 
    };
 
    length = length ? length : 10;
 
    return key.create(length);
  };
 
  var randint = function(n,m){
    var c = m-n+1;
    var num = Math.random() * c + n;
    return Math.floor(num);
  };
 
  var vCode = function(dom, options){
    this.codeDoms = [];
    this.lineDoms = [];
    this.initOptions(options);
    this.dom = dom;
    this.init();
    this.addEvent();
    this.update();
    this.mask();
  };
 
  vCode.prototype.init = function(){
    this.dom.style.position = "relative";
    this.dom.style.overflow = "hidden";
    this.dom.style.cursor = "pointer";
    this.dom.title = "点击更换验证码";
    this.dom.style.background = this.options.bgColor;
    this.w = this.dom.clientWidth;
    this.h = this.dom.clientHeight;
    this.uW = this.w / this.options.len;
  };
 
  vCode.prototype.mask = function(){
    var dom = document.createElement("div");
    dom.style.cssText = [
      "width: 100%",
      "height: 100%",
      "left: 0",
      "top: 0",
      "position: absolute",
      "cursor: pointer",
      "z-index: 9999999"
    ].join(";");
 
    dom.title = "点击更换验证码";
 
    this.dom.appendChild(dom);
  };
 
  vCode.prototype.addEvent = function(){
    var _this = this;
    _this.dom.addEventListener("click", function(){
      _this.update.call(_this);
    });
  };
 
  vCode.prototype.initOptions = function(options){
 
    var f = function(){
      this.len = 4;
      this.fontSizeMin = 20;
      this.fontSizeMax = 48;
      this.colors = [
        "green",
        "red",
        "blue",
        "#53da33",
        "#AA0000",
        "#FFBB00"
      ];
      this.bgColor = "#FFF";
      this.fonts = [
        "Times New Roman",
        "Georgia",
        "Serif",
        "sans-serif",
        "arial",
        "tahoma",
        "Hiragino Sans GB"
      ];
      this.lines = 8;
      this.lineColors = [
        "#888888",
        "#FF7744",
        "#888800",
        "#008888"
      ];
 
      this.lineHeightMin = 1;
      this.lineHeightMax = 3;
      this.lineWidthMin = 1;
      this.lineWidthMax = 60;
    };
 
    this.options = new f();
 
    if(typeof options === "object"){
      for(i in options){
        this.options[i] = options[i];
      }
    }
  };
 
  vCode.prototype.update = function(){
    for(var i=0; i<this.codeDoms.length; i++){
      this.dom.removeChild(this.codeDoms[i]);
    }
    for(var i=0; i<this.lineDoms.length; i++){
      this.dom.removeChild(this.lineDoms[i]);
    }
    this.createCode();
    this.draw();
  };
 
  vCode.prototype.createCode = function(){
    this.code = randstr(this.options.len);
  };
 
  vCode.prototype.verify = function(code){
    return this.code === code;
  };
 
  vCode.prototype.draw = function(){
    this.codeDoms = [];
    for(var i=0; i<this.code.length; i++){
      this.codeDoms.push(this.drawCode(this.code[i], i));
    }
 
    this.drawLines();
  };
 
  vCode.prototype.drawCode = function(code, index){
    var dom = document.createElement("span");
 
    dom.style.cssText = [
      "font-size:" + randint(this.options.fontSizeMin, this.options.fontSizeMax) + "px",
      "color:" + this.options.colors[randint(0, this.options.colors.length - 1)],
      "position: absolute",
      "left:" + randint(this.uW * index, this.uW * index + this.uW - 10) + "px",
      "top:" + randint(0, this.h - 30) + "px",
      "transform:rotate(" + randint(-30, 30) + "deg)",
      "-ms-transform:rotate(" + randint(-30, 30) + "deg)",
      "-moz-transform:rotate(" + randint(-30, 30) + "deg)",
      "-webkit-transform:rotate(" + randint(-30, 30) + "deg)",
      "-o-transform:rotate(" + randint(-30, 30) + "deg)",
      "font-family:" + this.options.fonts[randint(0, this.options.fonts.length - 1)],
      "font-weight:" + randint(400, 900)
    ].join(";");
 
    dom.innerHTML = code;
    this.dom.appendChild(dom);
 
    return dom;
  };
 
  vCode.prototype.drawLines = function(){
    this.lineDoms = [];
    for(var i=0; i<this.options.lines; i++){
      var dom = document.createElement("div");
 
      dom.style.cssText = [
        "position: absolute",
        "opacity: " + randint(3, 8) / 10,
        "width:" + randint(this.options.lineWidthMin, this.options.lineWidthMax) + "px",
        "height:" + randint(this.options.lineHeightMin, this.options.lineHeightMax) + "px",
        "background: " + this.options.lineColors[randint(0, this.options.lineColors.length - 1)],
        "left:" + randint(0, this.w - 20) + "px",
        "top:" + randint(0, this.h) + "px",
        "transform:rotate(" + randint(-30, 30) + "deg)",
        "-ms-transform:rotate(" + randint(-30, 30) + "deg)",
        "-moz-transform:rotate(" + randint(-30, 30) + "deg)",
        "-webkit-transform:rotate(" + randint(-30, 30) + "deg)",
        "-o-transform:rotate(" + randint(-30, 30) + "deg)",
        "font-family:" + this.options.fonts[randint(0, this.options.fonts.length - 1)],
        "font-weight:" + randint(400, 900)
      ].join(";");
      this.dom.appendChild(dom);
 
      this.lineDoms.push(dom);
    }
  };
 
  this.vCode = vCode;
 
}).call(this);

用法:

//container 为 验证码的DOM节点
var code = new vCode(container);
 
// 验证是否正确
// inputCode为用户输入的验证码
code.verify(inputCode); // return true or false
Javascript 相关文章推荐
javascript中的数字与字符串相加实例分析
Aug 14 Javascript
JS中prototype关键字的功能介绍及使用示例
Jul 21 Javascript
12种不宜使用的Javascript语法整理
Nov 04 Javascript
JS继承用法实例分析
Feb 05 Javascript
JS设置cookie、读取cookie
Feb 24 Javascript
一步步教大家编写酷炫的导航栏js+css实现
Mar 14 Javascript
Bootstrap实现导航栏的2种方式
Nov 28 Javascript
JavaScript获取当前时间向前推三个月的方法示例
Feb 04 Javascript
微信小程序 出现错误:{&quot;baseresponse&quot;:{&quot;errcode&quot;:-80002,&quot;errmsg&quot;:&quot;&quot;}}解决办法
Feb 23 Javascript
详解webpack es6 to es5支持配置
May 04 Javascript
Vue中import from的来源及省略后缀与加载文件夹问题
Feb 09 Javascript
es6数组之扩展运算符操作实例分析
Apr 25 Javascript
Bootstrap编写导航栏和登陆框
May 30 #Javascript
Bootstrap+jfinal退出系统弹出确认框的实现方法
May 30 #Javascript
Bootstrap+jfinal实现省市级联下拉菜单
May 30 #Javascript
基于Bootstrap里面的Button dropdown打造自定义select
May 30 #Javascript
BootStrap下jQuery自动完成的样式调整
May 30 #Javascript
JavaScript常用判断写法大全(推荐)
May 30 #Javascript
基于AngularJs + Bootstrap + AngularStrap相结合实现省市区联动代码
May 30 #Javascript
You might like
叶罗丽:为什么大家对颜冰这对CP非常关心,却对金茉两人十分冷漠
2020/03/17 国漫
php array_slice函数的使用以及参数详解
2008/08/30 PHP
php中Y2K38的漏洞解决方法实例分析
2014/09/22 PHP
Linux下安装oracle客户端并配置php5.3
2014/10/12 PHP
基于JQuery.timer插件实现一个计时器
2010/04/25 Javascript
验证javascript中Object和Function的关系的三段简单代码
2010/06/27 Javascript
javascript中xml操作实现代码
2011/11/21 Javascript
Nodejs全栈框架StrongLoop推荐
2014/11/09 NodeJs
JS运动框架之分享侧边栏动画实例
2015/03/03 Javascript
JavaScript实现多个重叠层点击切换效果的方法
2015/04/24 Javascript
详解js图片轮播效果实现原理
2015/12/17 Javascript
javascript中sort排序实例详解
2016/07/24 Javascript
用js控件div的滚动条,让它在内容更新时自动滚到底部的实现方法
2016/10/27 Javascript
使用Javascript简单计算器
2018/11/17 Javascript
Angular中innerHTML标签的样式不起作用的原因解析
2019/06/18 Javascript
Js利用正则表达式去除字符串的中括号
2020/11/23 Javascript
[55:47]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第三局
2016/02/27 DOTA
Python实现提取文章摘要的方法
2015/04/21 Python
python中判断文件编码的chardet(实例讲解)
2017/12/21 Python
Windows环境下python环境安装使用图文教程
2018/03/13 Python
Django 实现购物车功能的示例代码
2018/10/08 Python
解决Python3.5+OpenCV3.2读取图像的问题
2018/12/05 Python
pandas读取CSV文件时查看修改各列的数据类型格式
2019/07/07 Python
使用python实现多维数据降维操作
2020/02/24 Python
CSS3实现跳动的动画效果
2016/09/12 HTML / CSS
Canvas引入跨域的图片导致toDataURL()报错的问题的解决
2018/09/19 HTML / CSS
餐厅经理岗位职责和岗位目标
2014/02/13 职场文书
数学国培研修感言
2014/02/13 职场文书
幼儿园母亲节活动方案
2014/03/10 职场文书
文明生主要事迹
2014/05/25 职场文书
2014年社区党建工作汇报材料
2014/11/02 职场文书
Ajax 的初步实现(使用vscode+node.js+express框架)
2021/06/18 Javascript
mysql如何配置白名单访问
2021/06/30 MySQL
nginx lua 操作 mysql
2022/05/15 Servers
Java数据结构之堆(优先队列)
2022/05/20 Java/Android
canvas 中如何实现物体的框选
2022/08/05 Javascript