Node.js生成图形验证码--captchapng/ccap/trek-captcha

宋景福
2023-12-01

captchapng 是一个使用base64编码,只能生成数字验证码的node模块

使用npm安装captchapng

npm install --save captchapng

可以通过node.js的http模块搭建服务器,设置请求的接口地址,然后使用captchapng生成图形验证码返回给客户端;

var http = require('http');
var captchapng = require('captchapng');

http.createServer(function (request, response) {
    if(request.url === '/captcha') {
        var p = new captchapng(80, 30, parseInt(Math.random() * 9000 + 1000)); // width,height,numeric captcha
        p.color(0, 0, 0, 0);  // First color: background (red, green, blue, alpha)
        p.color(80, 80, 80, 255); // Second color: paint (red, green, blue, alpha)

        var img = p.getBase64();
        var imgbase64 = new Buffer(img, 'base64');
        response.writeHead(200, {
            'Content-Type': 'image/png'
        });
        response.end(imgbase64);
    } else {
        response.end('');
    }
}).listen(8181);

console.log('Web server started.\n http:\\\\127.0.0.1:8181\\captcha');

使用node运行这个js文件后,打开浏览器http:\127.0.0.1:8181\captcha,可以看到页面生成一个图形验证码。

也可以使用Express框架的路由Router,设置后端接口地址,生成图形验证码后返回给客户端。(可以设置图形验证码的时间戳,为了判断图形验证码是否过期)

export function loop(num, fn, ruledOut) {
  if (!Type.isNumber(num)) {
      return console.error('[Extend] loop: param 1 is not a number');
  }
  const result = [];
  for (let i = 0; i < num; i++) {
    if (ruledOut) {
      result.push(fn(i));
    } else {
      result[i] = fn(i);
    }
  }

  return result;
}

写一个controller来设置请求的路径,在<img>标签通过src属性来访问这个路径就可以得到图形验证码的图片来。


import express from 'express';
import Captchapng from 'captchapng';
import { loop } from '../app/lib/utils';

const router = express.Router();

router.get('/captcha', (req, res) => {
  const codeLength = 4;
  const captchaCode = loop(codeLength, () => (
    parseInt((Math.random() * 10000) % 10, 10)
  )).join('');

  const p = new Captchapng(70, 30, captchaCode); // width,height,numeric captcha
  p.color(0, 0, 0, 0);  // First color: background (red, green, blue, alpha)
  p.color(80, 80, 80, 255); // Second color: paint (red, green, blue, alpha)

  const img = p.getBase64();
  const imgbase64 = new Buffer(img, 'base64');

  if (req.session) {
    req.session.captcha = {
      timestamp: (new Date()).valueOf(),
      code: captchaCode
    };
  }

  res.setHeader('Content-Type', 'image/png');
  res.send(imgbase64);
});

export default router;

在前端页面中,如何实现点击图片更换图形验证码呢?

服务器端编写好生成验证码的方法,由于客户端浏览器会缓存URL相同的资源,可以使用随机数来重新请求:

document.getElementById('captcha').src = '/captcha?' + Math.random();

ccap可以自定义生成的验证码类型,默认是字母和数字混合的六位数,验证码图片还带有干扰线,安全性更高。不过,它好像不支持windows系统,在ios系统上可以使用。同时,它是用C++写的,在前端项目不用。

import express from 'express';
import Ccap from 'ccap';

const router = express.Router();

const ccap = new Ccap({
  width: 90,
  height: 35,
  offset: 20,
  quality: 300,
  fontsize: 30,
  generate: () => {  // Custom the function to generate captcha text
    const text = loop(4, () => (
      parseInt((Math.random() * 10000) % 10, 10)
    )).join('');
    return text;  // 这里的变量名只能是text,不能修改!!
  }
});

const ary = ccap.get();  // ary[0] is captcha's text,ary[1] is captcha picture buffer
const graphicCode = ary[0];
const buffer = ary[1];
if (req.session) {
  req.session.captcha = {
    timestamp: (new Date()).valueOf(),
    code: graphicCode
  };
}

if (req.query.base64) {
  res.send('data:image/png;base64,' + buffer.toString('base64'));
} else {
  res.send(buffer);
}

trek-captcha

'use strict'

const fs = require('fs');
const http = require('http');
const captcha = require('trek-captcha');

// async function run() {
//   const { token, buffer } = await captcha();

//   // console.log(token, buffer);

//   fs.createWriteStream('a.gif').on('finish', () => console.log(token)).end(buffer);
// }

// run();

http.createServer(async function(req, res) {
    const { token, buffer } = await captcha();

    console.log(token, buffer);
    res.setHeader('Content-Type', 'image/png');
    res.end(buffer);
}).listen(8123);
console.log('listening at port 8123');
 类似资料: