解决canvas中获取跨域图片数据的问题
背景
在一张图片添加相关文字,然后转化为base64数据,上传至服务器。当代码上线写完部署到测试环境,控制台报出如下错题:
Uncaught (in promise) DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported
经过排查,页面在请求图片时产生跨域情况,canvas认为该图片数据为 污染的数据
,是不安全的数据,无法导出base64数据。
为什么 canvas 认为跨域图片数据为 污染的数据
【解决canvas中获取跨域图片数据的问题】当请求跨域图片数据,而未满足跨域请求资源的条件时。如果canvas使用未经跨域允许的图片的原始数据,这些是不可信的数据,可能会暴露页面的数据。
请求图片资源 - 同域
Request Headers带有cookie。图片数据是被canvas信任的。
请求图片资源 - 跨域
默认情况下,直接请求跨域图片。因为不符合跨域请求资源的条件,图片数据是不被canvas信任的。
为了解决图片跨域资源共享的问题, 元素提供了支持的属性:
crossOrigin
,该属性一共有两个值可选:anonymous
和 use-credentials
,下面列举了两者的使用场景,以及满足的条件。
anonymous | use-credentials | |
---|---|---|
用途 | 匿名请求跨域图片资源,不会发送证书(比如cookie等) | 具名请求跨域图片资源,会携带证书数据 |
Request Headers | origin | origin、cookie |
Response headers | Access-Control-Allow-Origin | Access-Control-Allow-Origin、Access-Control-Allow-Credentials |
所需条件 | Access-Control-Allow-Origin 字段值需要包含请求域。 | Access-Control-Allow-Origin 字段值需要包含请求域,且不能为通配符 *。Access-Control-Allow-Credentials 字段值需要为 true,表明允许请求发送证书数据。 |
// page origin is https://a.comconst canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
const img = new Image();
img.crossOrigin = 'anonymous';
img.onload = () => {
context.drawImage(this, 0, 0);
context.getImageData(0, 0, img.width, img.height);
};
img.src = 'https://b.com/a.png';
结束语 总结了请求图片资源的所有场景:同域、匿名跨域、具名跨域,以及跨域成功所需的条件。希望可以帮到遇到类似问题的小伙伴。
参考
- CORS_enabled_image
- HTMLImageElement.crossOrigin
- 跨源资源共享(CORS)
- 跨源相关机制综述(三):crossorigin属性
- canvas-todataurl-securityerror
推荐阅读
- 热闹中的孤独
- parallels|parallels desktop 解决网络初始化失败问题
- Shell-Bash变量与运算符
- JS中的各种宽高度定义及其应用
- 2021-02-17|2021-02-17 小儿按摩膻中穴-舒缓咳嗽
- 深入理解Go之generate
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 异地恋中,逐渐适应一个人到底意味着什么()
- 我眼中的佛系经纪人
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售