后端接口返回图形验证码数据流,前端应如何渲染展示
我们不能直接将图片数据流展示到页面上,所以我们需要想办法让图片验证码正常的展示在页面中。此处我列举两种办法:通过img标签的src去请求接口、通过原生ajax进行数据流转换。
一、简介
在网页上的各种表单模块中我们经常会看到验证码的身影,常见的验证码类型有:短信验证码、图形验证码等等。而最近我在工作中就用到了图形验证码,但后端接口返回的并不是一个图片地址,而是图片数据流,像下面这样:
Network查看:
console.log输出一下:
我们不能直接将图片数据流展示到页面上,所以我们需要想办法让图片验证码正常的展示在页面中。此处我列举两种办法:通过<img>
标签的src去请求接口、通过原生ajax进行数据流转换。
二、具体方案
1、<img>
标签的src直接请求接口
<img>
标签的src属性,本来就是根据地址去请求对应图片数据的,既然接口返回的是图片验证码的数据流,所以我们可以直接通过 src 去请求该接口,然后接口返回的图形验证码就能通过<img>
展现出来,点击切换验证码时,我们可以在点击事件中通过js操作<img>
标签的src属性,使其重新请求接口,获取新的图片验证码:
具体代码:
<!-- 此处以vue为例,所以通过ref获取元素,修改src属性,原生js代码原理相同 -->
<img ref="vcImg" src="/api/v1/captcha" alt="验证码" @click="getVerifyCode()">
<script>
// 重新获取表单验证码
getVerifyCode () {
// 直接通过src去请求验证码图片 通过Math.random()防止缓存问题
this.$refs.vcImg.src = '/api/v123/captcha?' + Math.random()
},
</script>
页面效果:
2、原生ajax进行数据流转换
关于这种方式,首先我们需要借助ajax对象的responseType
属性来设置转换请求响应的数据类型,然后再通过window的URL对象的createObjectURL()
方法,将响应数据转换成URL对象,然后将该对象赋值给img
的src属性即可正常显示图形验证码。
具体代码:
<!-- 以Vue为例 -->
<img :src="src" alt="验证码" @click="getVerifyCode()">
<script>
export default {
data () {
return {
src: '' // 存储url对象
}
},
methods: {
// 获取表单验证码
getVerifyCode () {
// 暂存this对象
const that = this
// 获取window的URL对像 并做好浏览器兼容性处理
const windowUrl = window.URL || window.webkitURL
// 开始ajax请求
const xhr = new XMLHttpRequest()
// 验证码请求地址
const url = '/api/v123/captcha'
xhr.open('GET', url, true)
// 设置响应数据的类型 blod是将响应数据转换成二进制数据的Blob对象
xhr.responseType = 'blob'
xhr.onload = function () {
if (this.status === 200) {
const blob = this.response
// 将响应数据转换成url对象 赋值给src变量 传递给img
that.src = windowUrl.createObjectURL(blob)
}
}
xhr.send()
}
}
}
</script>
页面效果:
注意:
首先在设置responseType
属性时,我们需要确保服务器实际响应的数据类型与该格式兼容。如果服务器返回的数据与设置的 responseType
不兼容,则 response 的值将为null。
其次window的URL对象在不同的浏览器的调用方式可能有所不同,所以要做好兼容性处理。
最后就是在调用createObjectURL()
方法时,无论参数是否相同,每次调用都会创建一个新的url对象,虽然浏览器在document 卸载的时候,会自动释放它们,但是为了最佳的用户体验,最好还是选择合适的时机,通过URL.revokeObjectURL()
方法将之前的url对象给释放掉。
MDN相关文档:
更多推荐
所有评论(0)