html2canvas 跨域问题的全方位解读
2021年4月26加上allowTaint: true和useCORS: true依然显示空白html2canvas(document.querySelector(".poster"), {allowTaint: true,useCORS: true /*使用跨域*/}).then(canvas => {let imageTofile = document.getElementByI
2021年4月26
加上allowTaint: true和useCORS: true依然显示空白
html2canvas(document.querySelector(".poster"), {
allowTaint: true,
useCORS: true /*使用跨域*/
}).then(canvas => {
let imageTofile = document.getElementById("")
$('body').append(canvas)
var url = canvas.toDataURL('image/jpg');
// console.log(url);
});
问题:
截图区域的图品是服务器上的图片导致执行后因为跨域图片显示空白,上网百度说加上allowTaint: true和useCORS: true,但加上有依然显示空白,还有说先把图片转成base64再截图,尝试后依然报跨域无法显示图片
后来求助一位大佬后发现 将我从官网下的新版本换成“旧版本”的html2Canvas.js
后再设置了“allowTaint: true和useCORS: true”后问题尽然奇迹般地解决了(旧版本的JS:链接: https://pan.baidu.com/s/1LudA1rsdUPaqut0fj9niRA 提取码: u9p4),图片可以显示了
奇葩~~
此时将截图toDataURL时又报错
真的是一坑解决又入一坑,坑坑不断,在将canvas转url的时候又报错“Failed to execute ‘toDataURL’ on ‘HTMLCanvasElement’: Tainted canvases may not be exported.”
百度一天一无所获,各种复制黏贴的回答,让人头疼
转天偶然发现一篇文章完美解释 文章地址:https://www.jianshu.com/p/22bd5b98e38a
向大佬致敬
详情请点链接查看原文章
原因跟html2canvas库的工作原理有很大的关系。如前文所说,html2canvas库需要我们先提供一段DOM节点,然后它再读取并解析这一段DOM节点生成canvas对象。如果DOM节点中已经使用了标签的话,它也会解析这个标签的src属性,然后重新创建一个Image对象,给它添加crossOrigin="anonymous"属性后尝试以跨域的方式重新读取图片数据。需要注意的是,一般CDN上的图片都是带有缓存响应头并且会在浏览器端缓存的,而且缓存的不仅仅是图片数据,还有HTTP响应头。所以问题的根本原因我们就找到了,当html2canvas尝试以跨域的方式去读取图片数据时,它读取到的是浏览器的缓存数据,而且因为我们没有给DOM节点中的标签添加crossorigin="anonymous"属性,所以缓存数据是不带Access-Control-Allow-Origin响应头的,进而导致html2canvas库读取到的图片数据污染了生成的canvas对象,最终致使canvas导出数据报错。
看到这里已经真相大白了。所以我们要做的事情也很简单,就是给DOM节点中的每一个标签都加上crossorigin="anonymous"属性就可以了。再回过头说一下为什么之前的那个国人的文章虽然解决了问题但是却并没有找到问题的根本原因,因为他修改了html2canvas读取图片的源代码,给每一个Image的src属性添加了一个随机字符串,意外地避开了读取到缓存数据的问题,但是却会导致CDN的缓存被击穿。
最后总结一下,其实说了一大堆,我们要做的事情却很简单:
1、添加useCORS:true属性;
2、给要生成canvas的DOM中包含的每一个 img 标签添加crossorigin="anonymous"属性;
3、确保你的图片CDN服务器支持CORS访问,也就是会返回Access-Control-Allow-Origin等响应头;
更多推荐
所有评论(0)