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 相关文章推荐
多个iframe自动调整大小的问题
Sep 18 Javascript
js页面滚动时层智能浮动定位实现(jQuery/MooTools)
Aug 23 Javascript
jQuery实现视频作为全屏幕背景
Dec 18 Javascript
jQuery中next()方法用法实例
Jan 07 Javascript
PHP守护进程实例
Mar 06 Javascript
JQuery实现鼠标移动图片显示描述层的方法
Jun 25 Javascript
浅析JS异步加载进度条
May 05 Javascript
Avalon中文长字符截取、关键字符隐藏、自定义过滤器
May 18 Javascript
bootstrap table复杂操作代码
Nov 01 Javascript
vue实现的微信机器人聊天功能案例【附源码下载】
Feb 18 Javascript
javascript中call,apply,callee,caller用法实例分析
Jul 24 Javascript
vue实现户籍管理系统
May 29 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
两种php调用Java对象的方法
2006/10/09 PHP
PHP提示Notice: Undefined variable的解决办法
2012/11/24 PHP
解析PHP 使用curl提交json格式数据
2013/06/29 PHP
php给图片添加文字水印方法汇总
2015/08/27 PHP
46 个非常有用的 PHP 代码片段
2016/02/16 PHP
document对象execCommand的command参数介绍
2006/08/01 Javascript
window.open被浏览器拦截后的自定义提示效果代码
2007/11/19 Javascript
javascript自启动函数的问题探讨
2013/10/05 Javascript
JS简单的图片放大缩小的两种方法
2013/11/11 Javascript
Angularjs编写KindEditor,UEidtor,jQuery指令
2015/01/28 Javascript
jQuery制作简单柱状图实例
2015/01/28 Javascript
@ResponseBody 和 @RequestBody 注解的区别
2017/03/08 Javascript
vue 中自定义指令改变data中的值
2017/06/02 Javascript
iscroll.js滚动加载实例详解
2017/07/18 Javascript
原生js的ajax和解决跨域的jsonp(实例讲解)
2017/10/16 Javascript
vue实现tab切换外加样式切换方法
2018/03/16 Javascript
vue单页开发父子组件传值思路详解
2018/05/18 Javascript
socket io与vue-cli的结合使用的示例代码
2018/11/01 Javascript
element跨分页操作选择详解
2020/06/29 Javascript
Python中集合类型(set)学习小结
2015/01/28 Python
python类的方法属性与方法属性的动态绑定代码详解
2017/12/27 Python
Python实现统计给定列表中指定数字出现次数的方法
2018/04/11 Python
详解python如何引用包package
2020/06/07 Python
浅谈OpenCV中的新函数connectedComponentsWithStats用法
2020/07/05 Python
Python3以GitHub为例来实现模拟登录和爬取的实例讲解
2020/07/30 Python
python打包多类型文件的操作方法
2020/09/21 Python
努比亚手机官网:nubia
2016/10/06 全球购物
5个HTML5的常用本地存储方式详解与介绍
2021/03/27 HTML / CSS
医药代表个人求职信范本
2013/12/19 职场文书
捐赠仪式主持词
2014/03/19 职场文书
小学教师评语大全
2014/04/23 职场文书
医学求职信
2014/05/28 职场文书
幼儿园安全教育月活动总结
2015/05/08 职场文书
小学远程教育工作总结
2015/08/13 职场文书
【2·13】一图读懂中国无线电发展
2022/02/18 无线电
微软Win11 全新照片应用面向 Dev预览版推出 新版本上手体验图集
2022/09/23 数码科技