带CORS的IE9 jQuery AJAX返回“访问被拒绝”

时间:2012-04-19 15:56:28

标签: jquery internet-explorer-9 cross-domain jsonp cors

以下适用于所有浏览器除了IE (我在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'
            }
        );

我有另一个使用dataType: 'jsonp'的函数,但我不需要在这个AJAX调用上返回任何数据。我的最后一招将是返回JSONP中包含的一些乱码,以使其正常工作。

任何想法为什么IE搞砸了没有返回数据的CORS请求?

12 个答案:

答案 0 :(得分:149)

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

一个可用于在jQuery中支持此功能的插件,can be found herehttps://github.com/jaubourg/ajaxHooks/blob/master/src/xdr.js

修改 函数$.ajaxTransport注册一个运输工厂。 $.ajax使用内部运输器来执行请求。因此,我假设您应该像往常一样调用$.ajax。有关转运人和延长$.ajax的信息可以找到here

此外,可以找到此插件的更好版本here

另外两个注释:

  1. 对象XDomainRequest为introduced from IE8,在以下版本中不起作用。
  2. 来自IE10,CORS将是supported using a normal XMLHttpRequest
  3. 编辑2:http到https问题

      

    请求必须定位到与托管页面相同的方案

         

    此限制意味着如果您的AJAX页面位于   http://example.com,那么您的目标网址也必须以HTTP开头。   同样,如果您的AJAX页面位于https://example.com,那么您的   目标网址也必须以HTTPS开头。

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

答案 1 :(得分:62)

建立@dennisg接受的答案,我使用MoonScript的jQuery.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]);
            }
        }
    });
};

答案 2 :(得分:16)

有关如何使用“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

答案 3 :(得分:3)

问题是IE9及以下版本不支持CORS。 XDomainRequest只支持GET / POST和text/plain conten-type,如下所述:http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx

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

解决方案分为两部分。第一个是jquery脚本,它挂钩到jQuery ajax处理。如果发出了跨域请求并且浏览器是IE,它将自动调用Web服务器:

$.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/

答案 4 :(得分:1)

我刚刚提出了所有请求 JSONP ,因为它是我们所有支持的浏览器(IE7 +和常客)的唯一解决方案。请注意,您的答案在技术上适用于IE9,因此您可以得到正确的答案。

答案 5 :(得分:1)

在Internet Explorer 8及更新版本中使用jQuery获取跨域JSON

非常有用的链接:

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

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

希望这有助于某人。

答案 6 :(得分:1)

在MoonScript的解决方案的基础上,您可以尝试这样做:

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

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

答案 7 :(得分:0)

要解决此问题,还要检查您的ajax文件中是否包含一些.js: 我在ajax.php

中包含shadowbox.js时收到了Access denied错误

答案 8 :(得分:0)

我在我的开发机器上测试了一个CORS Web服务,并且只在IE中收到“访问被拒绝”错误消息。 Firefox和Chrome运行良好。事实证明这是由于我在ajax调用中使用localhost引起的!所以我的浏览器URL就像:

http://my_computer.my_domain.local/CORS_Service/test.html

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

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

一旦我更改了ajax调用以使用我的计算机IP而不是localhost,一切正常。

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

IE开发工具窗口“网络”选项卡还显示了CORS预检OPTIONS请求,后跟XMLHttpRequest GET,这正是我期望看到的。

答案 9 :(得分:0)

截至2015年初更新.xDomain是一个广泛使用的库,支持IE9上的CORS,并且有限的额外编码。

https://github.com/jpillora/xdomain

答案 10 :(得分:0)

尝试在IE8 / 9中使用jquery-transport-xdr jQuery插件进行CORS请求。

答案 11 :(得分:-1)

注意 - 注意

不要使用&#34; http://www.domain.xxx&#34;或&#34; http://localhost/&#34;或&#34; IP&gt;&gt; 127.0.0.1&#34;用于ajax中的URL。 仅使用没有地址的路径(目录)和页面名称。

错误状态:

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);