最近要給 node 項目加上驗證碼,找到了 node-canvas 這個庫,簡單地用了一下,發現仍是蠻好用的。javascript
git 地址:node-canvas前端
顧名思義,node-canvas 容許你在 node 端使用 canvas。在驗證碼這個使用場景裏,咱們能夠先生成驗證碼,而後在 canvas 上繪製,最後將圖片返回給前端。java
在安裝 node-canvas 以前,還須要安裝一些依賴。不一樣的系統須要安裝的不一樣,以 linux 和 mac 爲例:node
linux: sudo yum install cairo cairo-devel cairomm-devel libjpeg-turbo-devel pango pango-devel pangomm pangomm-devel giflib-devel
linux
mac: brew install pkg-config cairo pango libpng jpeg giflib
git
其餘參考 node-canvas#installationgithub
安裝完依賴後,執行 npm install canvas
便可。npm
經過獲取 canvas,能夠獲得 context 對象,而後就能夠像在前端同樣繪製圖形了canvas
const Canvas = require('canvas'); const canvas = new Canvas(100, 30), ctx = canvas.getContext('2d');
實際上我用到的 api 和前端的 canvas 是同樣的,繪製過程就很少解釋,能夠參考 canvas 的相關教程。api
下面是繪製一個 a + b = ?
的驗證碼
ctx.font = '24px "Microsoft YaHei"'; // 繪製文本 let drawText = (text, x) => { ctx.save(); // 旋轉角度 const angle = Math.random() / 10; // y 座標 const y = 22; ctx.rotate(angle); ctx.fillText(text, x, y); ctx.restore(); } // 隨機畫線 let drawLine = () => { const num = Math.floor(Math.random() * 2 + 3); // 隨機畫幾條彩色線條 for (let i = 0; i < num; i++) { const color = '#' + (Math.random() * 0xffffff << 0).toString(16); const y1 = Math.random() * height; const y2 = Math.random() * height; // 畫線 ctx.strokeStyle = color; ctx.beginPath(); ctx.lineTo(0, y1); ctx.lineTo(width, y2); ctx.stroke(); } } // 數字的文本隨機從小寫漢字、大寫漢字、數字裏選擇 const numArr = [ '〇一二三四五六七八九', '0123456789', '零壹貳叄肆伍陸柒捌玖' ]; // 第一個數字 const fir = Math.floor(Math.random() * 10); // 第二個數字 const sec = Math.floor(Math.random() * 10); // 隨機選取運算 const operArr = ['加', '減', '乘']; const oper = Math.floor(Math.random() * operArr.length); drawLine(); drawText(numArr[Math.floor(Math.random() * numArr.length)][fir], 10); drawText(operArr[oper], 40); drawText(numArr[Math.floor(Math.random() * numArr.length)][sec], 70); drawText('=', 100); drawText('?', 130); // 驗證碼值的計算 let captcha; switch(oper) { case 0: captcha = fir + sec; break; case 1: captcha = fir - sec; break; case 2: captcha = fir * sec; break; } // 存入 session req.session.captcha = captcha;
效果以下:
調用 canvas.toDataURL()
,能夠返回圖片的 base64 格式數據。
res.send({ status: 200, data: canvas.toDataURL() })
前端將該數據加到 img 的 src 屬性中便可。
在將項目部署到 linux 後,發現輸出顯示的圖片中的中文都變成了方框。
我參考了 redhat 6 下 node-canvas中文方框解決辦法 這篇文章,可是沒有所有運行,而是安裝了 yum groupinstall "Chinese Support"
,yum groupinstall Fonts
這兩個。
另外參考 用node-canvas繪製中文的時候亂碼怎麼解決? 問題裏的 5 樓,使用了微軟雅黑。
還有 issue#461,在字體兩側加上引號。
我按這三個作了,而後 重啓項目 就行了~