目录
前言
一、p调用接口获取验证码 + canvas画布渲染?
二、后端返回图片(图片流),前端显示
总结
前言
登录界面经常会有验证码,验证码的实现方式也有很多,我目前做过以下两种:
1.调用接口获取验证码 + canvas画布渲染
2.后端返回图片(数据流),前端显示
这两种方式都比较简单,本次项目技术栈为:vue2.6 + axsio ,接下来一起看看把~
一、p调用接口获取验证码 + canvas画布渲染?
这个比较简单,就是需要自己写一份canvas ,将后端获取过来得验证码显示出来,后续将验证码和识别码一起传递给后端,后端校验账户密码验证码是否一致。
1.编写canvas组件
这里我把他写成一个组件
<template>
<div class="s-canvas" >
<canvas ></canvas>
</div>
</template>
<script>
export default {
name: 'SIdentify',
data() {
return {
w: '',
h: '',
}
},
props: {
identifyCode: {
type: String,
default: '1234',
},
fontSi*: {
type: Number,
default: 26,
},
fontSizeMax: {
type: Number,
default: 30,
},
backgroundColorMin: {
type: Number,
default: 255,
},
backgroundColorMax: {
type: Number,
default: 255,
},
colorMin: {
type: Number,
default: 0,
},
colorMax: {
type: Number,
default: 160,
},
lineColorMin: {
type: Number,
default: 100,
},
lineColorMax: {
type: Number,
default: 255,
},
dotColorMin: {
type: Number,
default: 0,
},
dotColorMax: {
type: Number,
default: 255,
},
contentWidth: {
type: Number,
default: 121,
},
contentHeight: {
type: Number,
default: 50,
},
},
methods: {
//计算外盒子高度
boxSize() {
var contanier = ('canvas')
var canvas = ('s-canvas')
(canvas, 'canvas')
=
=
=
=
(, , '获取到得canvas宽高')
},
// 生成一个随机数
randomNum(min, max) {
return (() * (max - min) + min)
},
// 生成一个随机的颜色
randomColor(min, max) {
let r = (min, max)
let g = (min, max)
let b = (min, max)
return 'rgb(' + r + ',' + g + ',' + b + ')'
},
drawPic() {
let canvas = ('s-canvas')
let ctx = ('2d')
= 'bottom'
// 绘制背景
= (
,
)
// (,,"图形大小")
(0, 0, , )
// 绘制文字
for (let i = 0; i < ; i++) {
(ctx, [i], i)
}
(ctx)
(ctx)
},
drawText(ctx, txt, i) {
= (, )
=
(, ) + 'px SimHei'
let x = (i + 1) * ( / ( + 1))
let y = (, - 5)
var deg = (-45, 45)
// 修改坐标原点和旋转角度
(x, y)
((deg * ) / 180)
(txt, 0, 0)
// 恢复坐标原点和旋转角度
((-deg * ) / 180)
(-x, -y)
},
drawLine(ctx) {
// 绘制干扰线
for (let i = 0; i < 5; i++) {
= (, )
()
(
(0, ),
(0, )
)
(
(0, ),
(0, )
)
()
}
},
drawDot(ctx) {
// 绘制干扰点
for (let i = 0; i < 80; i++) {
= (0, 255)
()
(
(0, ),
(0, ),
1,
0,
2 *
)
()
}
},
},
watch: {
identifyCode() {
()
},
},
created() {},
mounted() {
()
()
},
}
</script>
<style lang="stylus" scoped>
.s-canvas {
width: 121px
height: 50px;
}
</style>
2.使用组件
引入该组件并命名为identifyCode
import IdentifyCode from '@/components/identifyCode'
<Identify-code :identifyCode="identifyCode"></Identify-code>
初始化得时候获取后端返回得验证码
created(){
()
}
//获取验证码
async getCode() {
try {
await XX().then((res) => {
= res
})
} catch (err) {
(err)
}
}
二、后端返回图片(图片流),前端显示
首先我们明确两个点:
- 普通请求接收的时候是json格式,图片流的接收模式可选两种:blob和arraybuffer。
- blob和arraybuffer本质上都是二进制数据。如果使用blob我们只需要用 (res)就可以得到图片链接;如果使用arraybuffer,我们需要将其转为base64的格式。
好啦,下面就开始啦~
首先我们先设置标签变量,如下:
<div class="getCaptcha" @click="getimgCaptcha()">
<img
:src="codeImg"
style="width:135px;height:40px;"
title="看不清,点击换一张"
loading="lazy"
alt="点击重新获取验证码"
srcset="">
</div>
请求设置,代码如下:
export function getCaptcha () {
return request({
url: /getCaptcha,
method: 'get',
responseType: 'blob' //选择接收方式为blob
})
}
图片处理,代码如下:
getCaptcha (e) {
getCaptcha().then(res => {
= (res) // 这里调用window的URL方法
(, '地址')
})
.catch(err => {
(err)
})
},
请求设置,代码如下:
// 图片验证码
export function getCaptcha () {
return request({
url: /getCaptch,
method: 'get',
responseType: 'arraybuffer'
})
}
图片处理,代码如下:
getCaptcha (e) {
getCaptcha().then(res => {
//1. btoa表示 base64转ASCII ,对应的还有 atob 表示 ASCII转base64
//2. Unit8Arrat() 是arraybuffer里面的一种类型
const url = 'data:image/png;base64,' + btoa(new Uint8Array(res).reduce((data, byte) => data + (byte), ''))
= url
(, '地址')
})
.catch(err => {
(err)
})
},
关于blod和arraybuffer的区别和具体用法,参考:前端二进制学习(三)
当然还有其它的二进制流,向上传文件或图片的时候用到的:File、FileReader、FormData,感兴趣可以自己去了解一下。
总结
以上就是今天要讲的内容,本文仅仅简单两种验证码的实现方式,当然还有其他的验证吗实现方式,感兴趣自己去看看把~