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
:选中GET
(这里根据需要选择就好,我这里选择这一个)允许Headers
:设置为*
暴露Headers
:设置为指定值或者不填(我这里没填)缓存时间
:默认0
就好返回 Vary: Origin
选项选不选都行,选的话费用高点,我这里不选
单击
确定
在这个 html2Canvas 截图案例中,只需要上面四步配置为(
来源:*
;Methods:GET
;Headers:*
;暴露Headers:不填
:缓存时间: 0
:不需要勾选 返回 Vary: Origin
)然后点确定即可
设置完如下所示:
截图方式进行处理
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>