一、简介
android系统定制开发在网页上的各种表单模android系统定制开发块中我们经常会看到验android系统定制开发证码的身影,常见的验证码类型有:、图形验证码等等。而最近我在工作中就用到了图形验证码,但后端接口返回的并不是一个图片地址,而是图片数据流,像下面这样:
Network查看:
console.log输出一下:
我们不能直接将图片数据流展示到页面上,所以我们需要想办法让正常的展示在页面中。此处我列举两种办法:通过<img>
标签的src去请求接口、通过进行数据流转换。
二、具体方案
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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
页面效果:
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>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
页面效果:
注意:
首先在设置responseType
属性时,我们需要确保服务器实际响应的数据类型与该格式兼容。如果服务器返回的数据与设置的 responseType
不兼容,则 response 的值将为null。
其次window的URL对象在不同的浏览器的调用方式可能有所不同,所以要做好兼容性处理。
最后就是在调用createObjectURL()
方法时,无论参数是否相同,每次调用都会创建一个新的url对象,虽然浏览器在document 卸载的时候,会自动释放它们,但是为了最佳的用户体验,最好还是选择合适的时机,通过URL.revokeObjectURL()
方法将之前的url对象给释放掉。
MDN相关文档: