canvas 中使用跨域的图片

一张跨域的图片直接在canvas中使用控制台是会给出警告的:

Error: SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.

原因是尽管不通过 CORS 就可以在 canvas 中使用其他来源的图片,但是这会污染画布,并且不再认为是安全的画布,这将可能在 canvas 检索数据过程中引发异常。

如果外部源的内容是 HTML <img> 或 SVG <svg> 元素,会阻止从 canvas 中读取数据。

如果外部源图片是作为 HTMLCanvasElement 或 ImageBitMap 获取的,且图片源不符合同源准则,会阻止读取 canvas 的内容。

解决方式:为图片提供设置 crossorigin 属性

代码:

<!DOCTYPE html>
<html lang="zh_CN">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="imageBox"></div>
    <script>
      let imageURL =
        "https://cdn.glitch.com/4c9ebeb9-8b9a-4adc-ad0a-238d9ae00bb5%2Fmdn_logo-only_color.svg?1535749917189";
      let imageDescription = "The Mozilla logo";
      downloadedImg = new Image();
      downloadedImg.crossOrigin = "Anonymous"; // 核心代码
      downloadedImg.addEventListener("load", imageReceived, false);
      downloadedImg.alt = imageDescription;
      downloadedImg.src = imageURL;
      function imageReceived() {
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");

        canvas.width = downloadedImg.width;
        canvas.height = downloadedImg.height;
        canvas.innerText = downloadedImg.alt;

        context.drawImage(downloadedImg, 0, 0);
        imageBox.appendChild(canvas);

        try {
          localStorage.setItem(
            "saved-image-example",
            canvas.toDataURL("image/png")
          );
        } catch (err) {
          console.error(`Error: ${err}`);
        }
      }
    </script>
  </body>
</html>
posted @ 2023-03-20 16:41  菌子乐水  阅读(496)  评论(0编辑  收藏  举报