Skip to content
html2canvas 截图 oss 图片防跨域

报错示例

项目有个页面要有截图功能,但是直接复制阿里云 oss 图片链接如下 在这里插入图片描述 能正常在页面显示,但是截图时会报出 oss 的跨域错误,如下截图代码::

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cross-Origin Screenshot Example</title>
    <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
    <style>
      #screenshot-area {
        width: 300px;
        padding: 20px;
        border: 1px solid #000;
        text-align: center;
      }
      img {
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div id="screenshot-area">
      <h2>Example Content</h2>
      <img
        src="https://vite-press.oss-cn-beijing.aliyuncs.com/htmlAndCss/33e0423a3da34fbcadc005958269d7be.png"
        alt="Placeholder Image"
      />
    </div>
    <button id="screenshot-btn">截图按钮</button>
    <div id="output"></div>

    <script>
      document
        .getElementById("screenshot-btn")
        .addEventListener("click", function () {
          let element = document.getElementById("screenshot-area");
          html2canvas(element, {
            useCORS: true, // 开启跨域配置
            allowTaint: false, // 开启跨域图片
            x: element.offsetLeft, // 防止长截图向上滑动时划到最下面时截图导致大片空白
            y: element.offsetTop,
            height: element.clientHeight - 3, //防止白边
          })
            .then(function (canvas) {
              let imgDataUrl = canvas.toDataURL();
              let imgElement = document.createElement("img");
              imgElement.src = imgDataUrl;
              document.getElementById("output").innerHTML = ""; // Clear previous output
              document.getElementById("output").appendChild(imgElement);
            })
            .catch(function (error) {
              console.error("Error creating canvas:", error);
            });
        });
    </script>
  </body>
</html>

效果图

在这里插入图片描述点击截图按钮后的效果图

在这里插入图片描述

解决方案

在阿里云 oss 配置跨域头

  • 找到 oss 管理控制台
  • 点击Bucket列表,然后单击目标 Bucket 名称(要确保 Bucket 是公共读权限)
  • 在左侧导航栏,选择数据安全 > 跨域设置
  • 跨域设置页面,单击创建规则
  • 创建跨域规则面板,按以下说明配置各项参数,其他参数保留默认配置即可
    • 来源:设置为*
    • 允许Methods:选中GETPOSTDELETEHEAD
    • 允许Headers:设置为*
    • 暴露Headers:设置为指定值或者不填
  • 单击确定

在这个 html2Canvas 截图案例中,只需要上面四步配置为( 来源:* Methods:GETHeaders:*暴露Headers:不填)然后点确定即可

设置完如下所示:

在这里插入图片描述

截图方式进行处理

js
<img
  src="https://vite-press.oss-cn-beijing.aliyuncs.com/htmlAndCss/33e0423a3da34fbcadc005958269d7be.png?1"
  alt="Placeholder Image"
  crossorigin="anonymous"
/>

上面更改的内容为:在 img 标签上加了个属性crossorigin="anonymous",在拼接路径后面加了个?1后面的 1 是随机值,防缓存,也可以写固定,不写?1的话加了上面说的属性图片不会显示

然后就可以正常截图了,代码里面只需要修改img标签的路径和新增的属性就可以了

效果图:

上面是原有图片,下面是截图的图片

在这里插入图片描述再提供一个方法用于返回当前时间戳,可以拼接到图片路径后面使用

js
function generateUniqueNumber() {
  // 获取当前时间戳(以毫秒为单位)
  const currentTimestamp = Date.now();
  return currentTimestamp;
}

// 调用函数
const uniqueNumber = generateUniqueNumber();
console.log(uniqueNumber);

完整代码

html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cross-Origin Screenshot Example</title>
    <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
    <style>
      #screenshot-area {
        width: 300px;
        padding: 20px;
        border: 1px solid #000;
        text-align: center;
      }
      img {
        width: 100%;
      }
    </style>
  </head>
  <body>
    <div id="screenshot-area">
      <h2>Example Content</h2>
      <img alt="Placeholder Image" crossorigin="anonymous" />
    </div>
    <button id="screenshot-btn">截图按钮</button>
    <div id="output"></div>

    <script>
      function generateUniqueNumber() {
        // 获取当前时间戳(以毫秒为单位)
        const currentTimestamp = Date.now();
        return currentTimestamp;
      }

      function setImgUrl() {
        document.querySelector(
          "#screenshot-area img"
        ).src = `https://aaabb1.oss-cn-beijing.aliyuncs.com/460ddb81703649459ff458b455927023.png?${generateUniqueNumber()}`;
      }

      // 加载图片链接地址
      setImgUrl();

      document
        .getElementById("screenshot-btn")
        .addEventListener("click", function () {
          let element = document.getElementById("screenshot-area");
          html2canvas(element, {
            useCORS: true, // 开启跨域配置
            allowTaint: false, // 开启跨域图片
            x: element.offsetLeft, // 防止长截图向上滑动时划到最下面时截图导致大片空白
            y: element.offsetTop,
            height: element.clientHeight - 3, //防止白边
          })
            .then(function (canvas) {
              let imgDataUrl = canvas.toDataURL();
              let imgElement = document.createElement("img");
              imgElement.src = imgDataUrl;
              document.getElementById("output").innerHTML = ""; // Clear previous output
              document.getElementById("output").appendChild(imgElement);
            })
            .catch(function (error) {
              console.error("Error creating canvas:", error);
            });
        });
    </script>
  </body>
</html>