IE8/9 中带有 jQ​​uery 和 XDomainRequest 的 CORS

Posted

技术标签:

【中文标题】IE8/9 中带有 jQ​​uery 和 XDomainRequest 的 CORS【英文标题】:CORS with jQuery and XDomainRequest in IE8/9 【发布时间】:2012-07-14 07:00:09 【问题描述】:

更新:我强烈建议不要在 XDomainRequest 上投入任何时间,因为它是一个非常糟糕的实现,有很多限制。它基本上只适用于对非 ssl 服务器的 GET 请求,因此您不妨使用 jsonp 或其他。


我正在使用 CORS 调用跨域 API,但 Internet Explorer 出现问题。通过 XDomainRequest 对象在 IE8 和 IE9 中应该可以使用 CORS,但是我无法正常工作..

JQuery refuses 为 XDomainRequest 提供本机支持,但是建议使用几个 jQuery 插件来添加此支持。这个topic 建议了两个这样的插件:jQuery.XDomainRequest.js 和xdr.js,据报道它们可以工作。 Afaik,插件应该自动覆盖jQuery.ajax 的行为。我找到了另一个插件here。

我放了一些演示页面,其中包含各自的插件 jQuery.XDomainRequest 和 xdr 和 jquery.ie.cors,它们对启用 CORS 的服务器执行 ajax 请求。这些页面在 Chrome 和 Firefox 中运行,但是 IE8/9 立即抛出权限被拒绝错误(甚至在发出请求之前)。这个MSDN post 建议添加另一个处理程序xhr.onprogress = function() ;,但我试过了,它也不起作用。

任何线索我做错了什么?我现在也使用 MS 虚拟服务器测试了 IE8,但它有完全相同的问题。

编辑:好的,所以我发现问题的一部分是我使用 POST over HTTPS。显然 XDomainRequest 不允许通过 HTTPS 进行 CORS。我可以切换到 HTTP,但我真的需要 POST。

Edit2:请参阅this issue on github 了解此故事的结尾。事实证明,当使用 HTTP POST 时,xDomainRequest 只能将请求正文(参数)编码为text/plain。这几乎使它毫无价值,因为每个人都使用application/x-www-form-urlencodedmultipart/form-data

【问题讨论】:

微软提供免费的 IE8 虚拟镜像,所以如果你有带宽就可以得到它。 (只是一个提示) 有一个简单的 hack/trick 可以让 jQuery CORS ajax 在 IE8 中工作......我想你可以通过搜索相关问题的答案在 *** 上找到它。 请在此处查看更新的自述文件以获取更多信息,包括一个有效的 jsFiddle 示例:github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest/blob/… 以上链接应该是:github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest/blob/… 这个问题来自 2013 年! DIE IE8/9。 【参考方案1】:

对于 IE8/9 中的 CORS 请求,您可以使用 jQuery 插件 jquery-transport-xdr

【讨论】:

这只是一个围绕相同XDomainRequest 方法的jQuery 包装器。它没有解决上述任何限制。【参考方案2】:

我编写了一个代理,如果使用 IE9 或更低版本,它会优雅地降级为代理。如果您使用的是 ASP.NET,则根本不必更改代码。

解决方案分为两部分。第一个是一个 jquery 脚本,它与 jQuery ajax 处理挂钩。如果跨域请求并且浏览器是IE,它会自动调用webserver:

$.ajaxPrefilter(function (options, originalOptions, jqXhr) 
    if (!window.CorsProxyUrl) 
        window.CorsProxyUrl = '/corsproxy/';
    
    // only proxy those requests
    // that are marked as crossDomain requests.
    if (!options.crossDomain) 
        return;
    

    if (getIeVersion() && getIeVersion() < 10) 
        var url = options.url;
        options.beforeSend = function (request) 
            request.setRequestHeader("X-CorsProxy-Url", url);
        ;
        options.url = window.CorsProxyUrl;
        options.crossDomain = false;
    
);

在您的网络服务器中,您必须接收请求,从X-CorsProxy-Url http 标头中获取值并执行 HTTP 请求并最终返回结果。

我的博文:http://blog.gauffin.org/2014/04/how-to-use-cors-requests-in-internet-explorer-9-and-below/

【讨论】:

【参考方案3】:

支持 POST 方法,并且要进行跨域 https:// 请求,您的调用页面也需要通过 https 加载。这是我找到的最好的文章,它详细解释了 XDomainRequest 的这些和其他限制:

http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

【讨论】:

这是一篇有几个陷阱的好文章。我过去曾多次提及它。另一个经常出现的:“请求的 Content-Type 标头只支持 text/plain” text/plain 限制使这个对象完全没有价值。恕我直言,完全浪费了微软的编程工作。 至少对于 JSON API 等常见用例,它并没有听起来那么糟糕。 Web 应用程序可以使用 XDomainRequest 以文本/纯文本形式发送 JSON 数据。服务器端逻辑只需要知道接受使用该 Content-Type 发送的 JSON。由于 CORS 支持已经需要在服务器端进行一些更改,因此无需付出太多额外的努力。

以上是关于IE8/9 中带有 jQ​​uery 和 XDomainRequest 的 CORS的主要内容,如果未能解决你的问题,请参考以下文章

WordPress 中带有 jQ​​uery 的 AJAX:AJAX 调用未将属性值传递给 PHP 函数

使用带有 jQ​​uery 插件的 Browserify

判断一个元素是不是有一个带有 jQ​​uery 的 CSS 类

带有 jQ​​uery 和 Bootstrap 3 的可折叠响应式侧边栏菜单

带有 jQ​​uery Ajax 的 JWT 令牌

通过单击带有 jQ​​uery 的锚点来平滑滚动元素