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 相关文章推荐
关于COOKIE个数与大小的问题
Jan 17 Javascript
不要使用jQuery触发原生事件的方法
Mar 03 Javascript
非jQuery实现照片散落桌子上,单击放大的LightBox效果
Nov 28 Javascript
两种方法解决javascript url post 特殊字符转义 + &amp; #
Apr 13 Javascript
Jquery 自定义事件实现发布/订阅的简单实例
Jun 12 Javascript
js省市区级联查询(插件版&amp;无插件版)
Mar 21 Javascript
微信小程序 中wx.chooseAddress(OBJECT)实例详解
Mar 31 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
Dec 08 Javascript
Angular网络请求的封装方法
May 22 Javascript
layui给下拉框、按钮状态、时间赋初始值的方法
Sep 10 Javascript
Ant Design Pro 下实现文件下载的实现代码
Dec 03 Javascript
jquery实现上传文件进度条
Mar 26 jQuery
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
php mail to 配置详解
2014/01/16 PHP
Zend Framework 2.0事件管理器(The EventManager)入门教程
2014/08/11 PHP
PHP动态柱状图实现方法
2015/03/30 PHP
PHP命名空间简单用法示例
2018/12/28 PHP
PHP实现的操作数组类库定义与用法示例
2019/05/24 PHP
PNG背景在不同浏览器下的应用
2009/06/22 Javascript
javascript权威指南 学习笔记之null和undefined
2011/09/25 Javascript
基于jquery的$.ajax async使用
2011/10/19 Javascript
js split 的用法和定义 js split分割字符串成数组的实例代码
2012/05/13 Javascript
纯JavaScript实现HTML5 Canvas六种特效滤镜示例
2013/06/28 Javascript
js 自动播放的实例代码
2013/11/19 Javascript
js与jquery获取父级元素,子级元素,兄弟元素的实现方法
2014/01/09 Javascript
使用JS批量选中功能实现更改数据库中的status状态值(批量展示)
2016/11/22 Javascript
BootStrap Fileinput初始化时的一些参数
2016/12/30 Javascript
Node.JS中事件轮询(Event Loop)的解析
2017/02/25 Javascript
使用JavaScript进行表单校验功能
2017/08/01 Javascript
vue基于mint-ui的城市选择3级联动的示例
2017/10/25 Javascript
vue 自定义右键样式的实例代码
2019/11/06 Javascript
JavaScript DOM常用操作代码汇总
2020/07/03 Javascript
js 数组当前行添加数据方法详解
2020/07/28 Javascript
pygame学习笔记(4):声音控制
2015/04/15 Python
深入解析Python中的线程同步方法
2016/06/14 Python
TensorFlow 模型载入方法汇总(小结)
2018/06/19 Python
详解Django中CBV(Class Base Views)模型源码分析
2019/02/25 Python
详解Selenium+PhantomJS+python简单实现爬虫的功能
2019/07/14 Python
IntelliJ 中配置 Anaconda的过程图解
2020/06/01 Python
纯CSS实现预加载动画效果
2017/09/06 HTML / CSS
移动端html5 meta标签的神奇功效
2016/01/06 HTML / CSS
DJI大疆无人机官方商城:全球领先的无人飞行器研发和生产商
2016/12/21 全球购物
英国最专业的健身器材供应商之一:Best Gym Equipment
2017/12/22 全球购物
宿舍卫生检讨书
2014/01/16 职场文书
高三生物教学反思
2014/01/25 职场文书
体育课课后反思
2014/04/24 职场文书
房屋租赁合同解除协议书
2014/10/11 职场文书
为什么RedisCluster设计成16384个槽
2021/09/25 Redis
Java使用JMeter进行高并发测试
2021/11/23 Java/Android