Vue 图片验证码实现【blob、base64】 您所在的位置:网站首页 滑动验证码图片怎么弄 Vue 图片验证码实现【blob、base64】

Vue 图片验证码实现【blob、base64】

2024-07-06 08:03| 来源: 网络整理| 查看: 265

实现效果

请添加图片描述

实现代码 1.给img添加属性 src

将src与js中定义的属性双向绑定,图片属性的来源

:src="verificationImg" @click

实现点击图片换一张验证码

@click="acquireVerification" 2.在进入需要验证码页面查询

因为我这里是通过对话框实现的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VUK1D7cd-1646028123555)(assets/验证码图片-20220227085640-z6s71j1.jpg)]

所以,在对话框打开的时候调用了 获取验证码的接口

openDiag(val, val2) { this.dialogVisible = val this.activeName = val2 this.acquireVerification() // 就是这个接口 }, 3.点击图片,获取验证码 async acquireVerification(){ const data = await api.verificationCode.verificationCode(); }

接口返回的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YppW9EYA-1646028123555)(assets/接口返回的数据-20220227085707-jbe1zuq.jpg)]

{ "code": 200, "message": "验证码", "data": { "image": "data:image/png;base64,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", "vCode": 1645923302817 } } 4.获取时间戳并保存 this.vCode = data.data.vCode.toString();

通过时间戳转换,我获取到了当前时间

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GWz1mRBy-1646028123556)(assets/image-20220227085759-9hb7sxw.png)]

因为此时用户还没有登录,所以对于后端来说,不知道该用户是谁。所以只能给一个临时的身份认证。即给一个毫秒级的时间戳

此时在后端,每次点击图片获取到验证码的时候,都已经构建了一个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)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K18E6abD-1646028123556)(assets/image-20220227090737-55kr0in.png)]

即 data:文件类型,数据

现在我们将base64格式的图片转换为文件

以逗号分割 let arr = dataUrl.split(',')

即可获得逗号前面的编码类型和编码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gkC5NAYe-1646028123556)(assets/以逗号分隔-20220227090410-0newl29.jpg)]

通过正则的惰性匹配获取内容

尽可能少的匹配字符

let type = arr[0].match(/:.*?);/)[1]

这里的意思就是从:到;尽可能少的匹配字符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xiU4yR5a-1646028123557)(assets/正则惰性匹配-20220227091908-4xia2z9.jpg)]

通过/获取后缀 let suffix = type.split('/')[1]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7zLUkWXT-1646028123557)(assets/获取后缀-20220227091918-goe6hb4.jpg)]

通过atob转换解码base64文件

Base64的编码与解码 - 术语表 | MDN (mozilla.org)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gpSYBURI-1646028123557)(assets/image-20220227092052-y3nu0if.png)]

let decodeBase64 = atob(arr[1])

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r2obaE9b-1646028123557)(assets/atob解码base64-20220227092154-slryz3n.jpg)]

类型为string

获取长度后,循环赋值到8位无符号整数数组内

每一个base64字符都代表6bit。因此,4个base64字符可以转换成3个字节(即占数组3位)

Uint8Array - JavaScript | MDN (mozilla.org)

创建之后,获取解码后的每一位unicode值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vaqEd5y7-1646028123558)(assets/image-20220227093643-2jrx0y7.png)]

let n = decodeBase64 .length let u8Arr = new Unit8Array(n); while(n --){ u8Arr = decodeBase64.charCodeAt(n) } 返回一个file对象

File - Web API 接口参考 | MDN (mozilla.org)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6w4BmRId-1646028123558)(assets/image-20220227101117-wwzw7x3.png)]

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 - Web API 接口参考 | MDN (mozilla.org)

现在我们创建一个Blob对象,利用Blob()构造函数

let blob = new Blob([imgFile], { type: 'image/png'}) 获取到图片的src地址 let imageUrl = (window.URL || window.wekitURL).createObjectURL(blob) 再赋值即可 this.verificationImg = imageUrl

完整代码

…… 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, }) },


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有