html2canvas资源跨域
在此就不详细介绍html2canvas 的安装与导入了,直接进入主题
第一:修改源码
①项目依赖包node_modules/html2canvas/dist/html2canvas.js;
②找到 Cache.prototype.loadImage函数
③替换源码
img.src = src;
img.src = /^data:image/.test(src) ? src : src + '?' + new Date().getTime();
第二:将跨域资源处理为静态资源,在这里处理成base64
/*
*src线上资源链接
*/
getBase64Image(src) {
return new Promise((resolve, reject) => {
let canvas=document.createElement("canvas"),
img = new Image(),
ctx = canvas.getContext("2d"),
base64 = '' ;
img.setAttribute("crossOrigin",'Anonymous')
img.src =/^data:image/.test(src) ? src : src + '?' + new Date().getTime()
img.οnlοad=()=>{
canvas.width=img.width
canvas.height=img.height
ctx.drawImage(img,0,0,img.width,img.height);
base64 = canvas.toDataURL("image/jpg");
resolve(base64)
}
img.onerror = reject
})
},
new Date().getTime()预防浏览器缓存
保存图片
downloadImage() {
let that=this
html2canvas(this.$refs['product'], {
backgroundColor: null,
useCORS: true,
allowTaint: true
}).then(canvas => {
let image = new Image();
//此处可不处理跨域
image.setAttribute("crossOrigin", "anonymous");
let src = canvas.toDataURL("image/png")
此处因为项目环境配置了钉钉环境,针对钉钉环境不同,做特殊处理
const isDDEnv = dd.env.platform !== 'notInDingTalk'
if(isDDEnv){
this.downloadFile(src )
}else{
image.src=/^data:image/.test(src) ? src : src + '?' + new Date().getTime()
}
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);
let url = canvas.toDataURL("image/png");
let a = document.createElement("a");
let event = new MouseEvent("click");
a.download = that.productDetails['productName'] || "photo";
a.href = url;
a.dispatchEvent(event);
}
}).catch(err => {
alert(err)
})
},
ios 静态内存溢出Maximum call stack size exceeded
此时运行到这里,安卓与pc一切正常,如果你在ios端未出现异常请忽略
当项目运行在ios端时 cath捕获异常Maximum call stack size exceeded
此时请查看当前所转换页面是否使用线上资源做背景图片,如果有请替换img(开发时所遇到的问题,未解决请寻找其它相应文章)
钉钉内部实现下载保存
移动端H5项目运行到钉钉内部环境时,上述下载保存图片失效,完全没有反应,此时查看钉钉开发文档调用对应jsapi--dd.biz.util.dowloadFile()安卓、ios端不支持,本人在这里做了一个中转处理,调用dd.biz.util.previewImage的api,可对图片预览,此时环境会有对应的下载按钮提供,也可长按保存,具体实现代码如下
async downloadFile(url){
//调用后端接口base64转线上资源地址
await API_Product.conversion({"base64":url})
.then((res)=>{
dd.biz.util.previewImage({
urls: [res],
current: res,
onSuccess : function(result) {
},
onFail : function(err) {
alert(err)
}
})
})
},