最近项目中遇到一个“保存至相册”的功能,由于是老功能重构,此部分没有改动,但是最近频繁出现问题:保存至相册时里面地图显示空白。
刚开始的时候也是一头雾水,正好好的功能咋出问题了,而且还是非必现问题。
后来上网查资料,发现可能跟图片url跨域相关,在本地跑工程前端设置了跨域代理,所以只能部署到服务器上看是什么问题,结果一查还真是图片跨域导致。
具体原理我就不赘述了,主要问题出在canvas .toDataURL()这行代码上。当时参考了一个大佬文章写的非常好,忘记收藏现在找不着了,呜呜
那么总结来说两种方案:
1、后端返回的图片url与当前工程部署在同一服务器避免跨域问题。
2、后端直接将base64格式的图片返回给前端。前端拿base64格式展示。
以上都是避免产生跨域问题,解决这个问题非常好的手端。
但是,我们的后端有点忙,不愿意配合情况下,下下策来了,前端自己将图片转base64:
//图片转base64
const getBase64Pic = function(src, callback, outputFormat) {
var xhr = new XMLHttpRequest();
xhr.open('GET', src, true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (xhr.status == 200) {
var uInt8Array = new Uint8Array(xhr.response);
var i = uInt8Array.length;
var binaryString = new Array(i);
while (i--) {
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var base64 = window.btoa(data);
var dataUrl = "data:" + (outputFormat || "image/png") + ";base64," + base64;
callback.call(this, dataUrl);
}
};
xhr.send();
}
调用时:
getBase64Pic(this.queryObj.mapFilePath,function(base64Img){
if(base64Img){
that.mapImg=base64Img;
console.log("获取base64小区地图成功");
}else{
this.$toast("小区地图获取失败");
}
})
但是不建议前端转base64,图片较大的时候会用时比较长,用户体验不好。
还有这个问题还跟缓存有关系,但是我还没整太明白。