前几天在做需求的时候突然被加了个新P,是在H5页面上展示一个二维码,为了“用户拥有更好的体验”,pm告诉我要在页面上有个点击保存二维码类似的按钮可以点击(内心毫无波澜),以为使用a链接用href指向该图片地址,再加上个download属性就大功告成了,但是后来才知道这个二维码图片是另一个服务生成的,host是不一样的,这就很烦于是写了个方法来下载这个图片。。
话不多说直接上代码
downImg() {
let image = new Image();
// 解决跨域 canvas 污染问题
image.setAttribute("crossOrigin", "anonymous");
image.src = document.getElementById("images").src;
image.onload = function() {
let canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
let context = canvas.getContext("2d");
context.drawImage(image, 0, 0, image.width, image.height);
canvas.toBlob(function(blob) {
saveAs(blob, "qrcode.png");
});
};
}
其实这里用到了第三方的库 file-saver中的saveAs方法,想使用这段代码请自行导入
兼容性问题
一开始我使用的并不是blob(binary large object)而是将跨域的图片使用canvas转换成base64格式进行保存,但是这样Chrome浏览器是可以的但是到了很多手机上的默认浏览器这样操作下载不了图片,于是实现这个功能的难点就来了————兼容很多不同的手机浏览器。
三星的手机上貌似都是OK的,但是小米的机型默认的手机浏览器这种方法进行下载的时候浏览器貌似是识别不了文件,总是显示下载失败(这个问题是QA发现的)于是我就换成了
canvas.toBlob(function(blob) {
saveAs(blob, "qrcode.png");
});
这样一试确实OK了,但是跑到百度和UC浏览器上测试的时候尼玛又下载不了(我真是服了),而且在IOS12+上面的Safari上也是不能直接就下载(很烦),同事的iOS13+是可以的,不知道咱也不知道不同的版本有啥毛病。
这样一搞我觉跟pm说咱们直接提示长按保存吧别搞乱七八糟的,测试着长按是OK的,但是在 iOS12+ 上面又出现问题了,貌似是将Safari的长按功能给禁止了于是我在img的 css上面加了这样一段代码:
-webkit-touch-callout: default;
之后又试了试发现虽然在 ios12+ 上面可以实现长按弹出功能框了但是,点击保存图片并没有啥子用处,图片并没有被保存下来,说实话我慌了,这咋搞不能说这个需求我做不来吧。。。
后来在网上搜帖子的时候看到了,网友说iOS的一个bug,因为我的 二维码内容是一段普通的string,但是iOS12。。。的机制是在保存的时候并识别,所以只能保存内容是链接的二维码,所以即使点击了保存按钮也不会被保存下来。。。
好吧,我服了,不搞了不搞了溜了溜了