Javascript 被跨域数据污染的画布
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13674835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Canvas tainted by cross-origin data
提问by clwen
I'm loading a motion jpeg from third-party site, which I can trust. I'm trying to getImageData()but the browser (Chrome 23.0) complains that:
我正在从我可以信任的第三方站点加载动态 jpeg。我正在尝试getImageData()但浏览器(Chrome 23.0)抱怨:
Unable to get image data from canvas because the canvas has been tainted by
cross-origin data.
There are some similar questions on SO, but they are using local file and I'm using third party media. My script runs on a shared server and I don't own the remote server.
SO上有一些类似的问题,但他们使用的是本地文件,而我使用的是第三方媒体。我的脚本在共享服务器上运行,我不拥有远程服务器。
I tried img.crossOrigin = 'Anonymous'or img.crossOrigin = ''(see this post on the Chromium blog about CORS), but it didn't help. Any idea on how can I getImageDataon a canvas with cross-origin data? Thanks!
我尝试过img.crossOrigin = 'Anonymous'或img.crossOrigin = ''(请参阅Chromium 博客上关于 CORS 的这篇文章),但没有帮助。关于如何getImageData在具有跨域数据的画布上的任何想法?谢谢!
采纳答案by Paul Kaplan
You cannot reset the crossOrigin flag once it is tainted, but if you know before hand what the image is you can convert it to a data url, see Drawing an image from a data URL to a canvas
一旦被污染,您就无法重置 crossOrigin 标志,但如果您事先知道图像是什么,您可以将其转换为数据 URL,请参阅 将图像从数据 URL 绘制到画布
But no, you cannot and should not be using getImageData() from external sources that don't support CORS
但是不,您不能也不应该使用来自不支持 CORS 的外部来源的 getImageData()
回答by J?rn Berkefeld
While the question is very old the problem remains and there is little on the web to solve it. I came up with a solution I want to share:
虽然这个问题很老了,但问题仍然存在,而且网络上几乎没有可以解决的问题。我想出了一个我想分享的解决方案:
You can use the image (or video) without the crossoriginattribute set first and test if you can get a HEAD request thru to the same resource via AJAX. If that fails, you cannot use the resource. if it succeeds you can add the attribute and re-set the source of the image/video with a timestamp attached which reloads it.
您可以先使用不设置crossorigin属性的图像(或视频),然后测试是否可以通过 AJAX 向同一资源发送 HEAD 请求。如果失败,您将无法使用该资源。如果成功,您可以添加该属性并重新设置图像/视频的来源,并附上重新加载它的时间戳。
This workaround allows you to show your resource to the user and simply hide some functions if CORS is not supported.
此解决方法允许您向用户显示您的资源,并在不支持 CORS 时隐藏某些功能。
HTML:
HTML:
<img id="testImage" src="path/to/image.png?_t=1234">
JavaScript:
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 */
});
Tested and working in IE10+11 and current Chrome 31, FF25, Safari 6 (Desktop). In IE10 and FF you might encounter a problem if and only if you try to access http-files from a https-script. I don't know about a workaround for that yet.
在 IE10+11 和当前的 Chrome 31、FF25、Safari 6(桌面)中测试和工作。在 IE10 和 FF 中,当且仅当您尝试从 https 脚本访问 http 文件时,您可能会遇到问题。我还不知道有什么解决方法。
UPDATE Jan 2014:
2014 年 1 月更新:
The required CORS headers for this should be as follows (Apache config syntax):
为此所需的 CORS 标头应如下所示(Apache 配置语法):
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Headers "referer, range, accept-encoding, x-requested-with"
the x-header is required for the ajax request only. It's not used by all but by most browsers as far as I can tell
仅 ajax 请求需要 x-header。据我所知,不是所有人都使用它,但大多数浏览器都使用它
回答by Kristopher Ives
Also worth noting that the CORS will apply if you are working locally regardless of if the resource is in the same directory as the index.htmlfile you are working with. For me this mean the CORS problems disappeared when I uploaded it to my server, since that has a domain.
另外值得注意的是,如果您在本地工作,无论资源是否与index.html您正在使用的文件位于同一目录中,CORS 都将适用。对我来说,这意味着当我将它上传到我的服务器时 CORS 问题消失了,因为它有一个域。
回答by Manish Mittal
You can use base64 of the image on canvas, While converting into base64 you can use a proxy URL (https://cors-anywhere.herokuapp.com/) before your image path to avoid cross-origin issue
您可以在画布上使用图像的 base64,在转换为 base64 时,您可以在图像路径之前使用代理 URL ( https://cors-anywhere.herokuapp.com/) 以避免跨域问题
check full details here
在此处查看完整详细信息
https://stackoverflow.com/a/44199382/5172571
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
})

