html2canvas截图oss图片防跨域

77 阅读2分钟

报错示例

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

<!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, // 开启跨域图片
      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:不填)然后点确定即可

设置完如下所示:

在这里插入图片描述

截图方式进行处理

<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标签的路径和新增的属性就可以了

效果图:

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

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

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

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

完整代码

<!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, // 开启跨域图片
            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>