IE10 和图像/画布的跨域资源共享 (CORS) 问题

Posted

技术标签:

【中文标题】IE10 和图像/画布的跨域资源共享 (CORS) 问题【英文标题】:IE10 and Cross-origin resource sharing (CORS) issues with Image / Canvas 【发布时间】:2013-06-02 02:51:52 【问题描述】:

我的印象是 Internet Explorer 10 完全支持 CORS,但现在我不确定了。

我们有一个使用多个域并读取图像数据的 JS/html5 应用程序。我们正在从另一个域加载 JS 中的图像,将图像 imageDraw()ing 到我们的画布,然后在画布上使用 getImageData。 (我们没有使用跨域 XMLHttpRequests)。为此,我们必须在提供图像的服务器上设置响应标头:

access-control-allow-origin: *
access-control-allow-credentials: true

并在加载前在 JS 中的图像对象上设置这个:

image.crossOrigin = 'Anonymous'; //Also tried lowercase

这适用于所有新浏览器,除了 IE10,当我们尝试读取数据时会引发安全错误。

SCRIPT5022: SecurityError

IE10 是否需要做更多工作才能将这些跨域图像视为无污染?

更新:

我注意到this answer 回答了上一个问题。 有趣的是this JSFiddle 也不适用于 IE10 - 谁能确认这在他们的 IE10 中不起作用?

【问题讨论】:

设置Access-Control-Allow-Origin 可能是必要的,但有时还不够。尝试在此处设置答案中给出的额外选项:***.com/questions/667519/… 尝试使用浏览器点击test-cors.appspot.com/#technical。如果这暴露了问题,那么您可能无能为力。 @user568109 - 我现在添加了该答案中提到的额外标题,但不幸的是我仍然看到同样的问题。 @UpTheCreek 同意——我刚刚在 Opera 中对其进行了测试,它也可以正常工作。因此,如果 IE 被正确标记为“不支持”,那就是奇怪的了。您是否尝试将image.crossOrigin 设置为"anonymous"(小写)或true?我认为您发布的大写版本是规范正确的,但也许 IE 实现了错误? 我已经为我正在做的一个项目做了很多测试,我会在网站的图标上做一些计算。 IE9 和 IE10 都不支持 <canvas> 中的图像资源的 CORS。我最终编写了一个代理来获取图像,以使图像请求不违反同源规则。对不起。 【参考方案1】:

不幸的是,即使正确设置了 CORS 标头,IE10 仍然是唯一不支持绘制到 Canvas 的图像的 CORS 的流行浏览器。但是通过 XMLHttpRequest 可以解决这个问题:

var xhr = new XMLHttpRequest();
xhr.onload = function () 
    var url = URL.createObjectURL(this.response), img = new Image();
    img.onload = function () 
        // here you can use img for drawing to canvas and handling
        // ...
        // don't forget to free memory up when you're done (you can do this as soon as image is drawn to canvas)
        URL.revokeObjectURL(url);
    ;
    img.src = url;
;
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.send();

【讨论】:

效果很好。我花了 2 个多小时才找到相同的解决方案。我只是希望我早点找到它。 这在我们关心的所有浏览器中都非常有用,除了 android Stock 浏览器。在 Android Chrome、ios Safari、IE10+、Chrome 和 FF 中测试。很烦人! 有没有办法测试“toDataURL”是否会抛出安全错误,如果是的话使用这个方法? @MrHunter 嗯,没试过,但你可以在toDataURL 附近尝试常规的try-catch,看看是否可行。 > xhr.open 行中的“url”是什么意思。只是您尝试加载的原始图片 URL。【参考方案2】:

已确认:IE10 不支持 HTML 5 画布中的 CORS 图像。请参阅 RReverser's answer 寻求解决方法。

编辑

抱歉,我之前没有处理过 CORS 图像,并认为这个问题是关于 AJAX 请求的。

根据Mozilla Developer Network,您需要将image.crossOrigin设置为anonymoususe-credentials。此外,根据今天的那个页面,IE、Safari 或 Opera 不支持这些属性。 This test 是为了证明 IE9 不支持它,而且在 IE10 中似乎同样的测试仍然失败,所以即使 Safari 和 Opera 在编写 MDN 文章后添加了支持,但很有可能 IE10 仍然缺乏支持。

我能给你的唯一提示是,一般来说,allow-credentials 是 incompatible,带有通配符 allow-origin。删除允许凭据或在允许来源中回显请求来源。

以下是 AJAX 调用,不是图像或视频画布资源

IE10 的早期版本已知存在 AJAX 错误,

http://bugs.idsl.pl/ie/xhr.htm http://connect.microsoft.com/IE/feedback/details/771552/i-e-10-and-the-post-method

所以它可能是另一个浏览器错误。话又说回来,CORS 看起来很棘手。我推荐以下步骤来调试 CORS 问题。

    将浏览器指向http://test-cors.appspot.com/#technical 以获取兼容性报告。如果出现任何故障,则说明您的浏览器存在错误或缺少对 CORS 的支持。 如果一切顺利,请使用测试发送的 CORS 标头作为起点,让您的 CORS 请求正常工作。然后一次更改一个标头并重新测试,直到您以应用程序所需的方式获得标头,或者遇到无法解释或解决的故障。 如有必要,发布一个关于破坏 CORS 请求的微小更改的问题,同时发布工作“之前”和失败的“之后”。如果您可以包含一个可运行的示例,它总是有帮助的。

CORS 测试客户端和服务器(Google App Engine 的 Python 脚本)的完整代码可在 https://github.com/rapportive-oss/cors-test 获得,以帮助您入门。

【讨论】:

谢谢 - 不幸的是仍然没有运气。 1 报告一切正常,但是我在测试的每个响应中都指定了所有标题,但我仍然收到安全错误。我不相信这个测试真的在测试“一切”——例如。 1) 没有一个响应标头使用通配符 access-control-allow-origin 设置 2) 它根本没有测试 drawImage 或 getImageData,并且 3) 它没有测试 image.crossOrigin = "Anonymous" 功能。 顺便说一句 - 我找到了一个完美显示问题的 JSFiddle (jsfiddle.net/WLTqG/29) - 请参阅我更新的背景问题。 感谢您的额外提示。关于不兼容性 - 我的理解是 access-control-allow-credentials 是使用“image.crossOrigin”所必需的,所以我们可能无法放弃它。正如您所说,动态允许来源标头可能是一种选择,但是 TBH 我没有看到使用这两种标头有任何问题。 如果将image.crossOrigin 设置为anonymousaccess-control-allow-credentials不需要的。仅在设置为use-credentials 时才需要。通过 AJAX 调用,我看到在设置使用凭据时,allow-origin 通配符始终被拒绝,这就是 CORS AJAX 测试器不使用通配符来源的原因。我想我们看到 Canvas 污染的规则有些不同,但如果您不需要凭据来访问图像,那么您可以删除 allow-credentials 标头并排除它作为问题的可能来源。 感谢您的澄清。我现在删除了access-control-allow-credentials。 (不幸的是并没有导致 IE 问题)

以上是关于IE10 和图像/画布的跨域资源共享 (CORS) 问题的主要内容,如果未能解决你的问题,请参考以下文章

SSM的跨域问题解决

SSM的跨域问题解决

画布中图像的 CORS 设置

Ajax跨域:jsonp还是CORS

使用 Angular 和 NodeJs (CORS) 的跨域请求

跨子域的跨域资源共享 (CORS)