Vue 图片验证码实现【blob、base64】
实现效果实现代码1.给img添加属性<div class="in_code"><img:src="verificationImg"@click="acquireVerification"/></div>src将src与js中定义的属性双向绑定,图片属性的来源:src="verificationImg"@click实现点击图片换一张验证码@click="acqui
实现效果
实现代码
1.给img
添加属性
<div class="in_code">
<img
:src="verificationImg"
@click="acquireVerification"
/>
</div>
src
将src
与js中定义的属性双向绑定,图片属性的来源
:src="verificationImg"
@click
实现点击图片换一张验证码
@click="acquireVerification"
2.在进入需要验证码页面查询
因为我这里是通过对话框实现的
所以,在对话框打开的时候调用了 获取验证码的接口
openDiag(val, val2) {
this.dialogVisible = val
this.activeName = val2
this.acquireVerification() // 就是这个接口
},
3.点击图片,获取验证码
async acquireVerification(){
const data = await api.verificationCode.verificationCode();
}
接口返回的数据
{
"code": 200,
"message": "验证码",
"data": {
"image": "data:image/png;base64,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",
"vCode": 1645923302817
}
}
4.获取时间戳并保存
this.vCode = data.data.vCode.toString();
通过时间戳转换,我获取到了当前时间
因为此时用户还没有登录,所以对于后端
来说,不知道该用户是谁。所以只能给一个临时的身份认证。即给一个毫秒级的时间戳
此时在后端,每次点击图片获取到验证码的时候,都已经构建了一个key-value
键值对,每一个时间戳对应一个验证码,对应一个人
5.获取image
image:是图像
在网络中,会通过base64
编码,以字符串形式发送图片。所以现在我们需要解码
data:image/png;base64,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
这一串为Data URL scheme语法
Base64 - MDN Web Docs Glossary: Definitions of Web-related terms | MDN (mozilla.org)
即
data:文件类型,数据
现在我们将base64格式的图片转换为文件
- 以逗号分割
let arr = dataUrl.split(',')
即可获得逗号前面的编码类型和编码
- 通过正则的惰性匹配获取内容
尽可能少的匹配字符
let type = arr[0].match(/:.*?);/)[1]
这里的意思就是从:
到;
尽可能少的匹配字符
- 通过
/
获取后缀
let suffix = type.split('/')[1]
- 通过
atob
转换解码base64文件
let decodeBase64 = atob(arr[1])
类型为string
- 获取长度后,循环赋值到8位无符号整数数组内
每一个base64字符都代表6bit。因此,4个base64字符可以转换成3个字节(即占数组3位)
Uint8Array - JavaScript | MDN (mozilla.org)
创建之后,获取解码后的每一位unicode值
let n = decodeBase64 .length
let u8Arr = new Unit8Array(n);
while(n --){
u8Arr = decodeBase64.charCodeAt(n)
}
- 返回一个file对象
return new File([u8Arr] , `${fileNmae}.${suffix}`,{
type: type
})
base64转换成文件-完整代码
base64ImgtoFile(dataurl, filename = 'file') {
debugger
let arr = dataurl.split(',')
let type = arr[0].match(/:(.*?);/)[1]
let suffix = mime.split('/')[1]
let decodeBase64 = atob(arr[1])
let n = bstr.length
let u8Arr = new Uint8Array(n)
while (n--) {
u8Arr[n] = decodeBase64.charCodeAt(n)
}
return new File([u8Arr], `${filename}.${suffix}`, {
type: type,
})
},
6.获取imageURL
- 创建一个blob
blob在MDN中的定义是一个不可变、原始数据的类文件对象。它的数据可以按照文本或二进制格式进行兑取,也可以转换成
ReadableStream
来用来数据操作
现在我们创建一个Blob对象,利用Blob()
构造函数
let blob = new Blob([imgFile], { type: 'image/png'})
- 获取到图片的src地址
let imageUrl = (window.URL || window.wekitURL).createObjectURL(blob)
- 再赋值即可
this.verificationImg = imageUrl
完整代码
<div class="in_code">
<img :src="verificationImg" @click="acquireVerification" />
</div>
……
export default {
data() {
verificationImg: '',
}
async acquireVerification() {
const data = await api.verificationCode.verificationCode()
this.vCode = data.data.vCode.toString()
let base64Img = data.data.image
var imgFile = this.base64ImgtoFile(base64Img)
// this.verificationImg = imgFile
let blob = new Blob([imgFile], { type: 'image/png' })
let imageUrl = (window.URL || window.webkitURL).createObjectURL(blob)
this.verificationImg = imageUrl
},
base64ImgtoFile(dataurl, filename = 'file') {
debugger
let arr = dataurl.split(',')
let type = arr[0].match(/:(.*?);/)[1]
let suffix = mime.split('/')[1]
let decodeBase64 = atob(arr[1])
let n = bstr.length
let u8Arr = new Uint8Array(n)
while (n--) {
u8Arr[n] = decodeBase64.charCodeAt(n)
}
return new File([u8Arr], `${filename}.${suffix}`, {
type: type,
})
},
更多推荐
所有评论(0)