IE9 jQuery AJAX with CORS returns "Access is denied"

The following works in all browsers except IE (I'm testing in IE 9).

jQuery.support.cors = true;
...
$.ajax(
url + "messages/postMessageReadByPersonEmail",
{
crossDomain: true,
data: {
messageId       : messageId,
personEmail     : personEmail
},
success: function() {
alert('marked as read');
},
error: function(a,b,c) {
alert('failed');
},
type: 'post'
}
);

I have another function which uses dataType: 'jsonp', but I don't need any data returned on this AJAX call. My last resort will be to return some jibberish wrapped in JSONP just to make it work.

Any ideas why IE is screwing up with a CORS request that returns no data?

145259 次浏览

这是一个已知的带有 jQuery 的 bug。JQuery 团队“没有计划在内核中支持这一点,而且更适合作为插件。”(见 this comment)。 IE 使用 XMLHttpRequest,但是使用另一个名为 XDomainRequest的对象。

在 jQuery 中有一个插件 可以支持这一点,它是 可以在这里找到: https://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js

剪辑 函数 $.ajaxTransport注册一个传输器工厂。$.ajax使用 internally传输器来执行请求。因此,我 假设你应该能够像往常一样调用 $.ajax。关于转运蛋白和扩展 $.ajax的信息可以找到 给你

此外,这个插件的一个可能更好的版本可以找到 给你

另外两点注意事项:

  1. 对象 XDomainRequest 是 由 IE8引入,在以下版本中不能工作。
  2. 从 IE10 CORS 将是 使用普通的 XMLHttpRequest 支持

编辑2: http 到 https 问题

请求必须针对与宿主页面相同的方案

这个限制意味着如果您的 AJAX 页面位于 HTTP://example.com ,则目标 URL 也必须以 HTTP 开头。 Similarly, if your AJAX page is at https://example.com, then your 目标 URL 也必须以 HTTPS 开头。

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

I just made all requests JSONP because it was the only solution for all of our supported browsers (IE7+ and the regulars). Mind you, your answer technically works for IE9 so you have the correct answer.

基于@dennisg 提供的可接受答案,我使用 MoonScript 的 XDomainRequest.js成功地完成了这项工作。

以下代码在 Chrome、 Firefox 和 IE10中运行正常,但在 IE9中失败。我只是简单地包含了这个脚本,现在它在 IE9中自动工作了。(可能有8个,但我还没有测试过。)

var displayTweets = function () {
$.ajax({
cache: false,
type: 'GET',
crossDomain: true,
url: Site.config().apiRoot + '/Api/GetTwitterFeed',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
for (var tweet in data) {
displayTweet(data[tweet]);
}
}
});
};

Getting a cross-domain JSON with jQuery in Internet Explorer 8 and newer versions

非常有用的链接:

Http://graphicmaniacs.com/note/getting-a-cross-domain-json-with-jquery-in-internet-explorer-8-and-later/

可以帮助解决从 X 域请求返回 json 的问题。

希望这对谁有帮助。

关于如何使用“ jQuery-ajaxTransport-XDomainRequest”插件完成这项工作的完整说明可以在这里找到: Https://github.com/moonscript/jquery-ajaxtransport-xdomainrequest#instructions

这个插件得到了积极的支持,可以处理 HTML、 JSON 和 XML。该文件也托管在 CDNJS 上,因此您可以直接将该脚本放入页面,而不需要进行额外的设置: Http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.1/jquery.xdomainrequest.min.js

要解决这个问题,还要检查 Ajax 文件中是否包含了一些.js,名为: 我在 ajax.php 中包含 Shadowbox.js 时收到 Access 拒绝错误

我正在我的开发机器上测试一个 CORS Web 服务,并且在 IE 中得到了“访问被拒绝”的错误消息。Firefox 和 Chrome 运行良好。原来这是由于我在 ajax 调用中使用了 localhost 造成的!所以我的浏览器网址是这样的:

Http://my_computer.my_domain.local/cors_service/test.html

我在 test.html 中的 ajax 调用是这样的:

//fails in IE
$.ajax({
url: "http://localhost/CORS_Service/api/Controller",
...
});

Everything worked once I changed the ajax call to use my computer IP instead of localhost.

//Works in IE
$.ajax({
url: "http://192.168.0.1/CORS_Service/api/Controller",
...
});

IE dev 工具窗口“ Network”选项卡还显示了 CORS PreFlight OPTION 请求后跟 XMLHttpRequest GET,这正是我所期望看到的。

The problem is that IE9 and below do not support CORS. XDomainRequest do only support GET/POST and the text/plain conten-type as described here: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

因此,如果您想使用所有 HTTP 动词和/或 json 等,则必须使用其他解决方案。我已经写了一个代理,如果使用 IE9或更少,它将优雅地降级为代理。如果使用 ASP.NET,则根本不需要更改代码。

解决方案分为两部分。第一个是连接到 jQuery ajax 处理的 jQuery 脚本。如果发出跨域请求,浏览器是 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;
}
});

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

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

基于 MoonScript 的解决方案,你可以试试这个:

Https://github.com/intuit/xhr-xdr-adapter/blob/master/src/xhr-xdr-adapter.js

好处是,由于它是一个较低级别的解决方案,它将在 IE8/9上(尽可能地)支持 CORS 和其他框架,而不仅仅是 jQuery。我已经在 AngularJS 以及 jQuery 1.x 和2.x 中成功地使用了它。

从2015年初开始更新。 xDomain 是一个广泛使用的库,它支持 IE9上的 CORS,只需有限的额外编码。

Https://github.com/jpillora/xdomain

注意,注意

do not use "http://www.domain.xxx" or "http://localhost/" or "IP >> 127.0.0.1" for URL in ajax. 只使用路径(目录)和没有地址的页面名称。

错误状态:

var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'http://www.example.com/dir/getSecurityCode.php', true);
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);

真实状态:

var AJAXobj = createAjax();
AJAXobj.onreadystatechange = handlesAJAXcheck;
AJAXobj.open('POST', 'dir/getSecurityCode.php', true);   // <<--- note
AJAXobj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
AJAXobj.send(pack);

Try to use Jquery-Transport-xdr jQuery plugin for CORS requests in IE8/9.