一、captcha
`captcha.js`是一个生成验证码的插件,使用js和canvas生成的,确保后端服务被暴力攻击,简单判断人机以及系统的安全性,体积小,功能多,支持配置。 验证码插件内容,包含1、验证码插件-使用,2、验证码插件栗子,3、API介绍,4、支持浏览器 注意:基于本项目源码从事科研、论文、系统开发,"最好"在文中或系统中表明来自于本项目的内容和创意,否则所有贡献者可能会鄙视你和你的项目。 使用本项目源码请尊重程序员职业和劳动

插件源码地址:https://github.com/saucxs/captcha

文章首发地址:https://www.mwcxs.top/page/630.html


二、功能
+ 版本v 1.0.0
- 1、支持随机字符内容配置,字符大小配置,字符类型配置,字符绘制方式配置,字符长度配置等
- 2、支持点位置随机,数量配置,点半径的配置
- 3、支持线条位置随机,宽度配置,线条数量的配置
- 4、支持随机前景色配置,区间值[0, 255],可以使用默认值
- 5、支持随机背景色配置,区间值[0, 255],可以使用默认值
- 6、支持点击更新视图
- 7、支持浏览器谷歌浏览器,火狐浏览器,Safari,IE10+等 三、验证码插件-使用 不依赖与其他的插件,实现起来很容易,`captcha.js`是必须要引进的组件 3.1 本地引入封装的js文件 第一步:获取组件方式:`git clone https://github.com/saucxs/captcha.git` 第二步:clone后,在需要加验证码的相关页面引入验证码文件"captcha.js"以及准备好装验证码容器:
引入captcha内容
<script type="text/javascript" src="./captcha.js"></script>
装验证码的容器
<canvas width="240" height="90" id="captcha1"></canvas>

第三步:在确保页面DOM加载完毕之后,调用captcha的draw方法(手动加载):
 /*不传值,统一走默认值*/
let captcha1 = new Captcha();
captcha1.draw(document.querySelector('#captcha1'), r => {
console.log(r, '验证码1');
});

/*传值,参数配置值,选择性配置*/
let captcha2 = new Captcha({
lineWidth: 1, //线条宽度
lineNum: 6, //线条数量
dotR: 2, //点的半径
dotNum: 25, //点的数量
preGroundColor: [10, 80], //前景色区间
backGroundColor: [150, 250], //背景色区间
fontSize: 30, //字体大小
fontFamily: ['Georgia', '微软雅黑', 'Helvetica', 'Arial'], //字体类型
fontStyle: 'stroke', //字体绘制方法,有fill和stroke
content: '一个验证码abcdefghijklmnopqrstuvw生成的插件使用的是canvas显示', //验证码内容
length: 6 //验证码长度
});
captcha2.draw(document.querySelector('#captcha2'), r => {
console.log(r, '验证码2');
});
使用插件的效果地址1:https://www.mwcxs.top/static/testTool/demo/index.html

3.2 npm包引入

第一步:npm获取验证码组件: 
npm install captcha-mini
第二步:引入验证码模块:
import Captcha from 'captcha-mini'
或者
var Captcha = require("captcha-mini")

第三步
:在确保页面DOM加载完毕之后,调用captcha的draw方法(手动加载):
 /*不传值,统一走默认值*/
let captcha1 = new Captcha();
captcha1.draw(document.querySelector('#captcha1'), r => {
console.log(r, '验证码1');
});

/*传值,参数配置值,选择性配置*/
let captcha2 = new Captcha({
lineWidth: 1, //线条宽度
lineNum: 6, //线条数量
dotR: 2, //点的半径
dotNum: 25, //点的数量
preGroundColor: [10, 80], //前景色区间
backGroundColor: [150, 250], //背景色区间
fontSize: 30, //字体大小
fontFamily: ['Georgia', '微软雅黑', 'Helvetica', 'Arial'], //字体类型
fontStyle: 'stroke', //字体绘制方法,有fill和stroke
content: '一个验证码abcdefghijklmnopqrstuvw生成的插件使用的是canvas显示', //验证码内容
length: 6 //验证码长度
});
captcha2.draw(document.querySelector('#captcha2'), r => {
console.log(r, '验证码2');
});

四、原理
1、思路
现在我们需要一个对象,然后调用对象的某个方法可以将验证码画出来。所以我们需要一个构造函数,用来实例化对象。
function Regcode() {}

构造函数接受一些参数,用来定制验证码的点、线、字的各种属性(颜色、长短、大小等)。

  function Regcode(params = {}) {
let p = Object.assign({...}, params); // 这里有定义好的属性和默认值
Object.keys(p).forEach(k => { // 将所有属性组合后添加到this上
this[k] = p[k];
});
}

2、draw方法

首先我们需要一个 draw 方法,作为验证码的绘制方法。

draw 方法接收两个参数,canvas 的 dom 对象,用来创建绘图的2d对象。还需要一个回调函数 callback,用来接收每次绘制的文字。

我们把 draw 方法放在Regcode的原型上,这样所有的实例对象都可以继承这些方法,而不是自己独立有一套。

在 draw 方法中,可以想到的是,我们需要创建 canvas 的 2d对象,创建画布,然后开始依次绘制点、线、文字。

 Regcode.prototype.draw = function(dom, callback = function () {}) { // 绘图
// 获取canvas dom
if (!this.paint) { // 如果没有2d对象,再进行赋值操作
this.canvas = dom; // 保存到this指针,方便使用
if (!this.canvas) return;
this.paint = this.canvas.getContext('2d'); // 保存到this指针,方便使用
if (!this.paint) return; // 回调函数赋值给this,方便使用
this.callback = callback;
}
// 随机画布颜色,使用背景色
let colors = this.getColor(this.backgroundColor);
this.paint.fillStyle = `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, 0.8)`;
// 绘制画布
this.paint.fillRect(0, 0, this.canvas.width, this.canvas.height);
// 绘图
this.arc();
this.line();
this.font();
};

需要简单判断一下是否有 dom 对象和2d对象,其实应该判断参数是否为 dom 对象,可以通过判断节点类型或者通过 dom instanceof HTMLElement(谷歌和火狐支持)来判断。但是这里因为要求不高,所以只是简单判断。

3、随机颜色

需要注意的是,在创建画布的时候,我们使用了获取背景色的一个方法。在之前的需求中我们可以看到,最高频的两个词是随机和颜色,所以肯定是需要将这两个方法单独封装的。

随机颜色这里采用的是 rgb 的强度值(0 ~ 255, 由暗 -> 亮),需要指定两个颜色区间:前景色(文字、线条)和背景色(画布背景)。因为需要将文字和背景颜色区分,避免色值太接近无法识别,所以默认前景色区间 [10, 80],背景色区间 [150, 250]。
Regcode.prototype.getColor = function(arr) { // 随机获取颜色
let colors = new Array(3).fill(''); // 创建一个长度为3的数组,值都填充为 ''
colors = colors.map(v => this.getRand(...arr)); // 每个成员随机获取一个强度值重组为新数组
return colors;
};

因为 rgb 颜色通常表示为 rgba(0,0,0,0.8),最后一位是透明度,这里没有参加随机。所以只考虑前3个数,在指定的强度区间内,只需要依次随机出3个数就好。所以在上面的方法中,还需要做的就是随机在一个数值区间中取值。

    Regcode.prototype.getRand = function(...arr) { // 获取某个区间的随机数
arr.sort((a, b) => a - b); // 将传入的参数从小到大排序
return Math.floor(Math.random() * (arr[1] - arr[0]) + arr[0]);
};

4、绘制线条

有了随机颜色,绘制线条就方便多了。lineNum 用于指定绘制几条线,默认为2条。之前说过前景色(foregroundColor) 和 背景色 (backgroundColor)也是可以传参的,文字、线条、点都使用前景色。在绘制线条的时候,还需要计算出线条的随机起止坐标,在这里 canvas 的宽高范围内都允许,这样就可以做到随机长度。

 Regcode.prototype.line = function() { // 绘制线条
for (let i = 0; i < this.lineNum; i++) {
// 随机获取线条的起止坐标
let x = this.getRand(0, this.canvas.width), y = this.getRand(0, this.canvas.height),
endx = this.getRand(0, this.canvas.width), endy = this.getRand(0, this.canvas.width);
this.paint.beginPath(); // 开始绘制
this.paint.lineWidth = this.lineWidth;
// 随机获取路径颜色
let colors = this.getColor(this.foregroundColor); // 使用前景色
this.paint.strokeStyle = `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, 0.8)`;
// 指定绘制路径
this.paint.moveTo(x, y);
this.paint.lineTo(endx, endy);
this.paint.closePath();
this.paint.stroke(); // 进行绘制
}
};

5、绘制圆点

绘制圆点要注意的是需要随机获取圆心的位置,即分别随机获取在宽高范围内的 (x, y) 坐标。dotNum 是允许传入的需要绘制圆点的个数,默认为10,dotR 是半径,默认为 1。
 Regcode.prototype.arc = function() { // 绘制圆点
for (let i = 0; i < this.dotNum; i++) {
// 随机获取圆心
let x = this.getRand(0, this.canvas.width), y = this.getRand(0, this.canvas.height);
this.paint.beginPath(); // 指定圆周路径
this.paint.arc(x, y, this.dotR, 0, Math.PI * 2, false);
this.paint.closePath(); // 随机获取路径颜色
let colors = this.getColor(this.foregroundColor);
this.paint.fillStyle = `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, 0.8)`; // 绘制
this.paint.fill();
}
};

6、绘制文字

绘制文字稍微麻烦一些,需要先从定义好的验证码因子(允许通过 content 参数自定义,默认为 acdefhijkmnpwxyABCDEFGHJKMNPQWXY12345789,这里去掉了类似于字母 b 和 数字 6 这样的容易混淆的字符。)中,随机获取指定长度(允许通过参数自定义)的验证码。
Regcode.prototype.getText = function() { // 随机获取验证码
let len = this.content.length, str = '';
for (let i = 0; i < this.len; i++) { // 随机获取每个因子,组成验证码
str += this.content[this.getRand(0, len)];
}
return str;
};

绘制文字的时候,注意以下几点:

1、需要通过回调函数将当前绘制的文字输出。

2、需要指定文字的旋转角度、字体类型、文字颜色、绘制风格(填充或者不填充)。

3、需要获得文字的实际宽度,用来确定单个文字的活动范围。
 
Regcode.prototype.font = function() { // 绘制文字
let str = this.getText(); // 获取验证码
this.callback(str); // 利用回调函数输出文字,用于与用户输入验证码进行比对
// 指定文字风格
this.paint.font = `${this.fontSize}px ${this.fontFamily}`;
this.paint.textBaseline = 'middle'; // 设置文本基线,middle是整个文字所占方框的高度的正中。
// 指定文字绘制风格
let fontStyle = `${this.fontStyle}Text`;
let colorStyle = `${this.fontStyle}Style`;
for (let i = 0; i < this.len; i++) { // 循环绘制每个字
let fw = this.paint.measureText(str[i]).width; // 获取文字绘制的实际宽度
// 获取每个字的允许范围,用来确定绘制单个文字的横坐标
let x = this.getRand(this.canvas.width / this.len * i, (this.canvas.width / this.len) * i + fw/2);
// 随机获取字体的旋转角度
let deg = this.getRand(-6, 6);
// 随机获取文字颜色
let colors = this.getColor(this.foregroundColor);
this.paint[colorStyle] = `rgba(${colors[0]}, ${colors[1]}, ${colors[2]}, 0.8)`;
// 开始绘制
this.paint.save();
this.paint.rotate(deg * Math.PI / 180);
this.paint[fontStyle](str[i], x, this.canvas.height / 2);
this.paint.restore();
}
};

基本上就完成了。

五、其他

欢迎使用[watermark-dom](https://github.com/saucxs/watermark-dom)插件,功能:给B/S网站系统加一个很浅的dom水印插件。

欢迎使用[captcha-mini](https://github.com/saucxs/captcha)插件,功能:生成验证码的插件,使用js和canvas生成的

欢迎使用[watermark-image](https://github.com/saucxs/watermark-image)插件,目前功能:图片打马赛克

												

captcha.js一个生成验证码的插件,使用js和canvas生成的更多相关文章

  1. js手机移动端选择插件 mobileSelect.js

    一.mobileSelect获取方法 mobileSelect支持单选.多级联动.自定义回调函数.二次渲染.最新版本下载地址[2017-09-21更新]: https://github.com/onl ...

  2. JS+CSS3 360度全景图插件 - Watch3D.js

    日常闲扯 从上一篇文章到这篇中间快过了一年了,时间真滴过得快.不是在下中间没想过写新的文章,而是自己确实变懒了(体重+1 +1 +1 +1....) ..OTL...不过到最后觉得还是需要写点东西,不 ...

  3. JS - 超强大文本动画插件Textillate.js

    http://www.yyyweb.com/demo/textillate/ Textillate.js AsimplepluginforCSS3textanimations.

  4. Js 之常见手势操作插件 Hammer.js

    一.下载 链接:https://pan.baidu.com/s/1UbEtSbT1xcmdzzTCaWmW1A提取码:ldqy 二.案例 三.代码 <!DOCTYPE html> < ...

  5. 第二百七十节,Tornado框架-生成验证码图片,以及验证码结合Session验证

    Tornado框架-生成验证码图片,以及验证码结合Session验证 第一.生成验证码图片  生成验证码图片需要两个必须模块 1.python自带的random(随机模块) 2.Pillow()图像处 ...

  6. Js逆向-滑动验证码图片还原

    本文列举两个例子:某象和某验的滑动验证 一.某验:aHR0cHM6Ly93d3cuZ2VldGVzdC5jb20vZGVtby9zbGlkZS1mbG9hdC5odG1s 未还原图像: 还原后的图: ...

  7. 使用.Net Core实现的一个图形验证码

    SimpleCaptcha是一个使用简单,基于.Net Standard 2.0的图形验证码模块.它的灵感来源于Edi.Wang的这篇文章https://edi.wang/post/2018/10/1 ...

  8. python的random模块(生成验证码)

    python的random模块(生成验证码) random模块常用方法 random.random() #生成0到1之间的随机数,没有参数,float类型 random.randint(1, 3) # ...

  9. 转: 通过Servlet生成验证码图片

    孤傲苍狼 只为成功找方法,不为失败找借口! javaweb学习总结(九)—— 通过Servlet生成验证码图片 一.BufferedImage类介绍 生成验证码图片主要用到了一个BufferedIma ...

随机推荐

  1. notepad++中双击选中字符串高亮颜色设置

    notepad++ 中最好用的功能就是双击选中,本文档中所有相同的内容高亮 不过有个问题就是当文档特别大,而且注释比较多的时候,我选中的内容高亮为绿色不太好找,那怎么设置呢? 设置--语言格式设置-- ...

  2. JavaScript路线

    看到知乎上有大神回答的,感觉很不错,分享下 首先要说明的是,咱现在不是高手,最多还是一个半桶水,算是入了JS的门. 谈不上经验,都是一些教训. 这个时候有人要说,“靠,你丫半桶水,凭啥教我们”.您先别 ...

  3. ELK 架构之 Elasticsearch 和 Kibana 安装配置

    阅读目录: 1. ELK Stack 简介 2. 环境准备 3. 安装 Elasticsearch 4. 安装 Kibana 5. Kibana 使用 6. Elasticsearch 命令 最近在开 ...

  4. 多进程IPC与Python支持

    多进程IPC与Python支持 linux下进程间通信的几种主要手段简介: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因 ...

  5. Oracle聚合函数

    max(),min(),avg(),sum() 其中 avg(),sum()只能操作数字  , max(),min()能操作数字.日期.字母 等.

  6. linux下Clang和gcc的区别

    Clang 比 GCC 编译器的优势: 编译速度更快 编译产出更小 出错提示更友 好,比如 clang 在编译过程可以直接指出相对简单的出错位置以及它 “ 认为 ” 正确的方式 . 内置有静态分析工具 ...

  7. 【手记】ASP.NET提示“未能创建类型”处理

    我是在本机启动IIS Express调试一个ashx(一般处理程序)时遇到这个报错,网上的说法普遍有这么几种: 把bbb.ashx中的Class="aaa.bbb" 改为Class ...

  8. JVM 线上故障排查基本操作

    # 前言 对于后端程序员,特别是 Java 程序员来讲,排查线上问题是不可避免的.各种 CPU 飚高,内存溢出,频繁 GC 等等,这些都是令人头疼的问题.楼主同样也遇到过这些问题,那么,遇到这些问题该 ...

  9. When to use next() and return next() in Node.js

    Some people always write return next() is to ensure that the execution stops after triggering the ca ...

  10. Spring Boot 整合Spring Security 和Swagger2 遇到的问题小结

    How to configure Spring Security to allow Swagger URL to be accessed without authentication @Configu ...