captcha.js一个生成验证码的插件,使用js和canvas生成
`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和strokecontent: '一個驗證碼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和strokecontent: '一個驗證碼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 domif (!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)插件,目前功能:圖片打馬賽克
轉載于:https://www.cnblogs.com/chengxs/p/10480504.html
總結
以上是生活随笔為你收集整理的captcha.js一个生成验证码的插件,使用js和canvas生成的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle对日期date类型操作的函数
- 下一篇: 《剑指offer》第十八题(在O(1)时