项目开发中竟遇到如此诡异的二维码乱码问题
搞定第三方登录和扫描二维码问题,兄弟姐妹们是不是很头疼?用Axios发HTTP请求得数据,结果却是一堆乱七八糟的二进制编码,晕头转向?下面给大家分享一下我怎么应对这些问题的,包括遇到的难题、试过哪些办法,还有最后成功的解决方案!
一、问题初现与困惑
告诉你个事儿,我刚才上网搜二维码信息,用了Axios这个软件。你猜怎么着?它给我弄出一堆我看不明白的二进制码,头都大了!特别是现在天气这么热,我感觉脑子都快炸了,一片混乱。
就是找不到问题,只好继续找原因了。方法用过好几种,看请求头查验证参数啥的,就是找不着那个烦人的东西。我还想过把那些乱七八糟的字节转成图片瞧瞧,结果还是打不开。
二、采坑记录
试了好多次都不行,索性把每次试的过程和结果记下来找找规律。
既然图片链接要Token验证,那我就不搞它了呗,直接过!
2.接着,我尝试读取远程图片文件,结果不出所料地失败了。
var url = this.domain + "app/smartqq/getQRCode";
var image = document.createElement(‘img’);
image.crossOrigin = '';
image.src = url;
document.body.appendChild(image);
随便试了试Blob回应方式,没想到竟然成功了!
Blob的确帮了忙,不过我还是试着找别的路子看看,毕竟更棒的方法可能还有。
let fr = new FileReader();
let blob = new Blob([res.data],{type:"image/png"});
fr.readAsDataURL(blob); //读取文件内容,读取完成,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容。
let getImgUrl = new Promise((resolve,reject)=>{
fr.onload = function(){
var dataUrl = fr.result; //result属性为data:URL格式,与读取方式有关
resolve(dataUrl);
};
});
getImgUrl.then(res=>{
console.log(res);
});
三、深入分析问题根源
明白乱码原因后,我就想弄清楚为什么Axios不能处理二进制图片数据?简单说,Axios只能处理application/json或者text/plain这样的格式,遇到二进制数据就抓瞎了,结果就是一堆乱七八糟的字符。
四、选择Blob响应类型获取图片数据
this.$axios({
method: 'get',
url: this.domain + "app/smartqq/getQRCode", // 请求地址
data: {} , // 参数
responseType: 'blob' // 表明返回服务器返回的数据类型
}).then(
(res) => {
let blob = new Blob([res.data], {type: "image/png"});
let fileName = Date.parse(new Date())+".png" ;
if (window.navigator.msSaveOrOpenBlob) {
navigator.msSaveBlob(blob, fileName);
} else {
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
window.URL.revokeObjectURL(link.href);
}
});
搞定!现在只需要处理下思路。这次打算用Blob回应方式取图。你知道吗?Blob就是存储二进制数据的高手,超好用。调整了Axios的回应方式为Blob之后,果然成功拿到想要的图片数据!
五、Blob对象的应用与转换
搞定Blob之后,下一步就是要把它变成可在网页上看见的图片。不要怕js二进制流转换成图片,URL.createObjectURL()这个好帮手来了,它能把Blob变成临时链接,再放到图片标签的src属性里,图片就能亮相!
this.$axios.get(this.domain+'app/smartqq/getQRCode',{
responseType: 'arraybuffer'
}).then(response => {
return 'data:image/png;base64,' + btoa( new Uint8Array(response.data).reduce((data, byte) => data + String.fromCharCode(byte), '') )
}).then(response => {
var img = document.createElement('img');
img.src = response;
document.body.appendChild(img);
});
六、总结与反思
这次尝试给我上了一课,要处理二进制数,得挑好对的应对办法和计算方式!还学到怎么用Blob来理解,然后展示图片文件里的那些看不见摸不着的二进制数据。这次可真是长见识了,不仅提高了自己的技术水平,也让我对项目开发中的各种小细节有了更深的了解。
this.$axios.get(this.domain+'app/smartqq/getQRCode').then(response => {
console.log(response);
var blob = response.data;
var img = document.createElement("img");
img.onload = function(e) {
window.URL.revokeObjectURL(img.src);
};
img.src = window.URL.createObjectURL(blob);
document.body.appendChild(img);
});
七、向读者提出的问题
你有没有像我这样碰到过问题?咋解决的?教教我!咱们可以互相学习。还有,觉得这篇文章还行的话,就给个赞或者转发出去,让大家也看看呗!