画布被交叉原点数据污染



我正在从第三方网站加载一个我可以信任的运动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的这篇文章),但没有帮助。关于如何在具有交叉原点数据的画布上getImageData,有什么想法吗?谢谢

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

但是不,您不能也不应该使用来自不支持CORS 的外部源的getImageData()

虽然这个问题很老,但问题仍然存在,网络上几乎没有什么可以解决的。我想出了一个我想分享的解决方案:

您可以先使用不设置crossorigin属性的图像(或视频),然后测试是否可以通过AJAX向同一资源发送HEAD请求。如果失败,则无法使用该资源。如果成功,你可以添加属性并重新设置图像/视频的来源,并附上一个重新加载它的时间戳。

此解决方法允许您向用户显示资源,并在不支持CORS的情况下简单地隐藏一些函数。

HTML:

<img id="testImage" src="path/to/image.png?_t=1234">

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"

x-header仅用于ajax请求。据我所知,除了大多数浏览器外,其他浏览器都没有使用它

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

您可以在画布上使用图像的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
})

最新更新