html2canvas 踩坑 | 跨域导致渲染出空白图片的问题 - 图1
    问题描述:

    如图所示,本次踩的坑,就是对于跨域的图片,虽然它可以正常渲染到页面上,但是 html2canvas 却没法正常“截图”,截到的结果是空的,和预期不符。

    左侧容器中有一张图片 img1,但是该图片的 src 的值被浏览器判定为跨域了。(并且服务端也没进行额外处理)但是对于跨域的图片资源,浏览器想要把图片给正常渲染出来,完全是没问题的。问题出在对于跨域的图片资源,html2canvas 没法完成拍照。当我们使用 html2canvas 去拍照的时候,跨域的图片会被自动忽略……

    背景知识:对于 img 元素,它的 src 属性,除了可以是一个 url,还可以是一坨 base64 格式的字符串。当我们获取到一张图片的 url 时,就有办法通过 js 来将其转为 base64 格式。

    解决方案:将获取到的跨域的 url,转为 base64,然后再使用 html2canvas 来截图,此时就可以正常截取了。

    1. <!-- img1 图片正常渲染,但是 html2canvas 没法正常截图 -->
    2. <img src="跨域 url" />
    3. <!-- img2 图片正常渲染,且 html2canvas 可以正常截图 -->
    4. <img src="base64" />
    1. /**
    2. * 将 url 转为 base64
    3. * @param {String} src 跨域图片的 url
    4. * @param {String} cb 成功将 url 转为 base64 之后的回调
    5. */
    6. function iamgeToBase64(src, cb) {
    7. // 新建一个 Image 实例,去加载图片
    8. const imgIns = new Image();
    9. imgIns.crossOrigin = ""; // 解决跨域问题
    10. imgIns.src = src;
    11. // 图片加载完成后,使用 canvas 将其画出来,并转为 base64 格式
    12. imgIns.onload = () => {
    13. const canvas = document.createElement("canvas");
    14. canvas.width = imgIns.width;
    15. canvas.height = imgIns.height;
    16. const ctx = canvas.getContext("2d");
    17. ctx.drawImage(imgIns, 0, 0, imgIns.width, imgIns.height);
    18. const ext = imgIns.src
    19. .substring(imgIns.src.lastIndexOf(".") + 1)
    20. .toLowerCase();
    21. cb(canvas.toDataURL("image/" + ext));
    22. };
    23. }

    小结:「跨域导致渲染出空白图片的问题」上述方案可以解决该问题,但是具体原理并不了解,先知道咋解决就好。

    • 不熟悉 canvas
    • 不知道 base64 是啥,只知道它可以作为 img 的 src 来使