怎么解决canvas中获取跨域图片数据的问题?

简介: 怎么解决canvas中获取跨域图片数据的问题?

背景

在一张图片添加相关文字,然后转化为base64数据,上传至服务器

当代码上线写完部署到测试环境,控制台报出如下错题:

Uncaught (in promise) DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported

这是因为页面在请求图片时产生跨域情况,canvas认为该图片数据为污染的数据,是不安全的数据,无法导出base64数据

为什么 canvas 认为跨域图片数据为 污染的数据

当请求跨域图片数据,而未满足跨域请求资源的条件时

如果canvas使用未经跨域允许的图片的原始数据,这些是不可信的数据,可能会暴露页面的数据

请求图片资源 - 同域

Request Headers带有cookie。图片数据是被canvas信任的

请求图片资源 - 跨域

默认情况下,直接请求跨域图片。因为不符合跨域请求资源的条件,图片数据是不被canvas信任的。


为了解决图片跨域资源共享的问题, <img> 元素提供了支持的属性: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

image.png

代码示例

// page origin is https://a.com
const 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';

另外,跨域图片能正常裁剪(图片未转化成base64),应该满足三个条件:


img元素中设置crossorigin属性

图片允许跨域,设置响应头Access-Control-Allow-Origin

使用js方式请求图片资源, 需要避免使用缓存,设置url后加上时间戳,或者http头设置Cache-Control为no-cache

主要原因是:


如果使用跨域的资源画到canvas中,并且资源没有使用CORS去请求,canvas会被认为是被污染了, canvas可以正常展示,但是没办法使用toDataURL()或者toBlob()导出数据,见Allowing cross-origin use of images and canvas。 所以通过在img标签上设置crossorigin,启用CORS,属性值为anonymous,在CORS请求时不会发送认证信息,见HTML attribute: crossorigin。

在启用CORS请求跨域资源时,资源必须允许跨域,才能正常返回,最简单的方式设置响应头Access-Control-Allow-Origin

图片已经通过img标签加载过,浏览器默认会缓存下来,下次使用js方式再去请求,直接返回缓存的图片,如果缓存中的图片不是通过CORS 请求或者响应头中不存在Access-Control-Allow-Origin,都会导致报错

相关文章
|
5月前
|
前端开发
canvas图片操作
canvas图片操作
|
前端开发
canvas生成自定义大小图片
canvas生成自定义大小图片
|
1月前
|
前端开发 JavaScript API
为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片
使用1x1像素的透明GIF图片发送数据埋点请求,是因为这种方式可以隐蔽地传输数据,不干扰用户界面和体验,同时减少网络流量消耗,且易于实现跨域请求。
|
缓存 JavaScript 前端开发
解决阿里oss远程图片html2canvas生成海报时跨域问题(附代码)
解决阿里oss远程图片html2canvas生成海报时跨域问题(附代码)
1237 0
解决阿里oss远程图片html2canvas生成海报时跨域问题(附代码)
处理图片跨域问题
处理图片跨域问题
61 0
|
前端开发
使用SpringMvc跨服务器上传图片,Ajax异步刷新图片框显示图片功能请求不到后台,onChange事件没有激活的源码?
使用SpringMvc跨服务器上传图片,Ajax异步刷新图片框显示图片功能请求不到后台,onChange事件没有激活的源码?
101 0
使用SpringMvc跨服务器上传图片,Ajax异步刷新图片框显示图片功能请求不到后台,onChange事件没有激活的源码?
|
人工智能 前端开发 JavaScript
canvas 中如何实现自定义路径动画
前言 大家好!!又到周末了,最近项目忙完了,有时间写文章了。之前有粉丝问我, fly哥怎么实现自定义路径动画, 当时给他说的就是路径无非不就是直线 或者曲线。也就这两种, 直线的话 可以用直线方程, 曲线的话稍微复杂点 ,需要用贝塞尔曲线去做lerp。也就是动画的每一幁的算出路径的对应的坐标就可以了。但是这套方案学习成本太高了, 有没有一种更加简单的方式呢?本篇文章大概花费你5分钟, 你可以学到什么呢 svg 的 两个无敌api 后面介绍 封装了一个自定义路径动画函数 创建Path 制作动画前,先要拿到动画的路径,对此我们可以直接使用svg的path定义规则,比如我们定义了一条较为复杂的路径
canvas 中如何实现自定义路径动画
|
前端开发
前端解决第三方图片防盗链的办法 - html referrer 访问图片资源403问题
前端解决第三方图片防盗链的办法 - html referrer 访问图片资源403问题
638 0
|
机器学习/深度学习 Web App开发 移动开发
通过Canvas在浏览器中更酷的展示视频
有了Canvas可以更灵活的展示体验更好的视频,能够与页面更好的融合。
466 0
通过Canvas在浏览器中更酷的展示视频