canvas受到跨源数据的污染

我正在加载来自第三方网站的动作jpeg,我可以信任。 我正在尝试getImageData()但浏览器(Chrome 23.0)抱怨说:

 Unable to get image data from canvas because the canvas has been tainted by cross-origin data. 

在SO上有一些类似的问题,但他们使用的是本地文件,而我正在使用第三方媒体。 我的脚本在共享服务器上运行,我不拥有远程服务器。

我试过img.crossOrigin = 'Anonymous'img.crossOrigin = '' (请参阅Chromium博客上关于CORS的这篇文章 ),但它没有帮助。 关于如何在具有跨源数据的canvas上获取getImageData任何想法? 谢谢!

一旦被污染,您就无法重置crossOrigin标志,但如果您事先知道图像是什么,则可以将其转换为数据url,请参阅将图像从数据URL绘制到canvas

但不,你不能也不应该使用不支持CORS的外部源的getImageData()

虽然问题很严重,但问题仍然存在,网上很少有人能够解决这个问题。 我想出了一个我想分享的解决方案:

您可以在不crossorigin设置crossorigin属性的情况下使用图像(或video),并测试是否可以通过AJAX获取HEAD请求到同一资源。 如果失败,则无法使用该资源。 如果成功,您可以添加属性并重新设置图像/video的来源,并附加一个重新加载它的时间戳。

此解决方法允许您向用户显示您的资源,如果不支持CORS,只需隐藏一些function。

HTML:

  

JavaScript的:

 var target = $("#testImage")[0]; currentSrcUrl = target.src.split("_t=").join("_t=1"); // add a leading 1 to the ts $.ajax({ url: currentSrcUrl, type:'HEAD', withCredentials: true }) .done(function() { // things worked out, we can add the CORS attribute and reset the source target.crossOrigin = "anonymous"; target.src = currentSrcUrl; console.warn("Download enabled - CORS Headers present or not required"); /* show make-image-out-of-canvas-functions here */ }) .fail(function() { console.warn("Download disabled - CORS Headers missing"); /* ... or hide make-image-out-of-canvas-functions here */ }); 

在IE10 + 11和当前的Chrome 31,FF25,Safari 6(桌面)中进行了测试和工作。 在IE10和FF中,当且仅当您尝试从https脚本访问http文件时,可能会遇到问题。 我还不知道有关解决方法。

2014年1月更新:

这需要的CORS头应如下(Apache配置语法):

 Header set Access-Control-Allow-Origin "*" Header set Access-Control-Allow-Headers "referer, range, accept-encoding, x-requested-with" 

只有ajax请求才需要x-header。 据我所知,它并没有被大多数浏览器使用

另外值得注意的是,如果您在本地工作,则无论资源是否与您正在使用的index.html文件位于同一目录中,CORS都将适用。 对我来说这意味着当我将它上传到我的服务器时,CORS问题就消失了,因为它有一个域。

您可以在canvas上使用图像的base64,在转换为base64时,您可以在图像路径之前使用代理URL( https://cors-anywhere.herokuapp.com/ )以避免跨源问题

查看详细信息

https://stackoverflow.com/a/44199382/5172571

 var getDataUri = function (targetUrl, callback) { var xhr = new XMLHttpRequest(); xhr.onload = function () { var reader = new FileReader(); reader.onloadend = function () { callback(reader.result); }; reader.readAsDataURL(xhr.response); }; var proxyUrl = 'https://cors-anywhere.herokuapp.com/'; xhr.open('GET', proxyUrl + targetUrl); xhr.responseType = 'blob'; xhr.send(); }; getDataUri(path, function (base64) { // base64 availlable here })