效果图如下:

步骤:
1.安装jsencrypt,创建jsencrypt.js文件对从后端获取的验证码进行解密
import JSEncrypt from 'jsencrypt'
import { parseBigInt } from 'jsencrypt/lib/lib/jsbn/jsbn'
let privateKey = `xxxxxx...` ('BEGIN RSA PRIVATE KEY-----\n${加密的文本}\n-----END RSA PRIVATE KEY')
const publicKey ='xxxxxx...' ('BEGIN RSA PUBLIC KEY-----\n${加密的文本}\n-----END RSA PUBLIC KEY')
const encryptor = new JSEncrypt()
export function rsa_encrypt(word) {
encryptor.setPublicKey(publicKey)
return encryptor.encrypt(word)
}
export function rsa_decrypt(word, privateKey) {
encryptor.setPrivateKey(privateKey)
return encryptor.decrypt(word)
}
export function decrypt(data) {
const encrypt = new JSEncrypt()
encrypt.setPublicKey(publicKey)
const rsaKey = encrypt.getKey()
rsaKey.decrypt = function (ctext) {
let c = parseBigInt(ctext, 16)
let m = this.doPublic(c)
if (m == null) {
return null
}
return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3)
}
return encrypt.decrypt(data)
}
export function pkcs1unpad2(d, n) {
let b = d.toByteArray()
let i = 0
while (i < b.length && b[i] === 0) {
++i
}
++i
while (b[i] !== 0) {
if (++i >= b.length) {
return null
}
}
let ret = ''
while (++i < b.length) {
let c = b[i] & 255
if (c < 128) {
ret += String.fromCharCode(c)
} else if (c > 191 && c < 224) {
ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63))
++i
} else {
ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63))
i += 2
}
}
return ret
}
2.创建verfiycode.js文件,绘制验证码画布的方法
import { rsa_decrypt } from './jsencrypt.js'
const privateKey = 'xxxxxx...' ('BEGIN RSA PRIVATE KEY-----\n${加密的文本}\n-----END RSA PRIVATE KEY')
function CaptchaMini(params = {}) {
let middleParams = Object.assign(
{
lineWidth: 0.5,
lineNum: 2,
dotR: 1,
dotNum: 15,
preGroundColor: [10, 80],
backGroundColor: [150, 250],
fontSize: 20,
fontFamily: ['Georgia', '微软雅黑', 'Helvetica', 'Arial'],
fontStyle: 'fill',
content: '1234',
length: 4
},
params
)
Object.keys(middleParams).forEach(item => {
this[item] = middleParams[item]
})
this.canvas = null
this.paint = null
this.oricode = null
}
CaptchaMini.prototype.getRandom = function (...arr) {
arr.sort((a, b) => a - b)
return Math.floor(Math.random() * (arr[1] - arr[0]) + arr[0])
}
CaptchaMini.prototype.getColor = function (arr) {
let colors = new Array(3).fill('')
colors = colors.map(() => this.getRandom(...arr))
return colors
}
CaptchaMini.prototype.getText = function () {
debugger
let length = this.content.length
let str = ''
for (let i = 0; i < this.length; i++) {
str += this.content[this.getRandom(0, length)]
}
return str
}
CaptchaMini.prototype.line = function () {
for (let i = 0; i < this.lineNum; i++) {
let x = this.getRandom(0, this.canvas.width)
let y = this.getRandom(0, this.canvas.height)
let endX = this.getRandom(0, this.canvas.width)
let endY = this.getRandom(0, this.canvas.height)
this.paint.beginPath()
this.paint.lineWidth = this.lineWidth
let colors = this.getColor(this.preGroundColor)
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()
}
}
CaptchaMini.prototype.circle = function () {
for (let i = 0; i < this.dotNum; i++) {
let x = this.getRandom(0, this.canvas.width)
let y = this.getRandom(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.preGroundColor)
this.paint.fillStyle = 'rgba(' + colors[0] + ',' + colors[1] + ',' + colors[2] + ',' + '0.8)'
this.paint.fill()
}
}
CaptchaMini.prototype.font = function () {
let str = rsa_decrypt(this.content, privateKey)
console.log(str, 'str')
this.oricode = str
this.callback(str)
this.paint.font = this.fontSize + 'px ' + this.fontFamily[this.getRandom(0, this.fontFamily.length)]
this.paint.textBaseline = 'middle'
let fontStyle = this.fontStyle + 'Text'
let colorStyle = this.fontStyle + 'Style'
for (let i = 0; i < this.length; i++) {
let fontWidth = this.paint.measureText(str[i]).width
let x = this.getRandom(
(this.canvas.width / this.length) * i + 0.2 * fontWidth,
(this.canvas.width / this.length) * i + 0.5 * fontWidth
)
let deg = this.getRandom(-6, 6)
let colors = this.getColor(this.preGroundColor)
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()
}
}
CaptchaMini.prototype.draw = function (dom, callback = function () {}) {
if (!this.paint) {
this.canvas = dom
if (!this.canvas) return
else this.paint = this.canvas.getContext('2d')
this.callback = callback
this.canvas.onclick = () => {
this.drawAgain()
}
}
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.circle()
this.line()
this.font()
}
CaptchaMini.prototype.clear = function () {
this.paint.clearRect(0, 0, this.canvas.width, this.canvas.height)
}
CaptchaMini.prototype.drawAgain = function () {
this.clear()
this.draw(this.callbak)
}
export default CaptchaMini
3.准备canvas容器,进行绘制
<canvas id="captcha1" width="80" height="32" style="margin-left: 10px" @click="changeVerfiyCode"></canvas>
import Captcha from '/verfiycode.js'
const changeVerfiyCode = () => {
getCode().then(res => {
console.log('res', res)
genCaptcha(res.encryptVerifyCode)
})
}
const genCaptcha = str => {
captcha1 = new Captcha({
content: str
})
captcha1.draw(document.querySelector('#captcha1'), r => {
console.log(r, '验证码1')
})
}