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


123

以下内容适用于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请求?


由于没有一个建议的答案对我有用(我也必须将cookie传递到CORS请求中,这在使用XDomainRequest时是不可以的),因此可以采用以下解决方法:blog.gauffin.org/2014/04/…。代理救援!:p
wimvds 2014年

Answers:


150

这是jQuery 的已知错误。jQuery团队“没有计划在内核中支持此功能,因此更适合作为插件”。(请参阅此评论)。IE浏览器无法使用XMLHttpRequest的,但命名的替代对象XDomainRequest

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

编辑 该功能$.ajaxTransport注册运输厂。甲转运用于内部$.ajax执行请求。因此,我认为您应该能够$.ajax照常打电话。有关运输和扩展的信息$.ajax可以在这里找到。

另外,可以在此处找到该插件的更好版本。

其他两个注意事项:

  1. 对象XDomainRequest是从IE8引入的,在以下版本中将不起作用。
  2. 从IE10开始,将使用常规XMLHttpRequest支持 CORS 。

编辑2:HTTP到https问题

请求必须针对与托管页面相同的方案

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

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


12
插件的“更好的版本”是先天的。我只是将其包含在我的页面中,并自动修复了$ .ajax调用:)当然,假设您已经准备好所有必需的标头
加藤

5
要添加到dennisg答案中,xdr.js有一个错误-ajaxTransport回调将不会被直接调用。我必须根据stackoverflow.com/questions/12481560/…(将“ + *”添加为ajaxTransport调用的第一个参数)进行更改。
Volodymyr Otryshko

4
jQuery.XDomainRequest.js确保当前页面和远程页面均为http或https。这是否意味着您无法从http页面调用https API?
亚伦

2
值得注意的是,moonscripts github repo上链接的代码是旧版本,无法正常工作。请确保在以下位置获取最新版本:raw.github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest/…–
Clintm

3
@Aaron,添加到@HariKaramSingh的注释:更改协议(httphttps),域(google.combing.com),子域(mail.google.commaps.google.com)或协议(google.com:80-默认端口为google.com:8080)都将触发“跨域”请求。基本上/,URL中第一个之前的所有内容都必须相同。
allicarn 2014年

62

通过@dennisg建立可接受的答案,我使用jQuery.XDomainRequest.js成功完成了此任务的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]);
            }
        }
    });
};

3
jQuery.XDomainRequest.js插件正是我所需要的!我无法让iexhr.js插件来处理HTTP基本身份验证背后的请求,但是XDomainRequest却很吸引人!
詹姆斯·福特

这对我有用。我不需要Site.config()。apiRoot +(我假设它是针对Twitter的。
Nicholas Decker

@NicholasDecker Site.config()。apiRoot只是实现特定的代码,用于获取API的根URL,没有任何通用或特别之处。很高兴它有所帮助!
JackMorrissey

我希望这对我有用,但是我正在尝试发布。想知道这是否对我来说是问题。
Jack Marchetti

1
@cracker您是否只有POST问题?仔细检查jQuery之后脚本是否正在加载,并且您的调用与MoonScript的文档匹配。
JackMorrissey 2014年

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


1
效果很好-修复了问题。令人难以置信的是,这个问题存在于jQuery中,但是...谢谢!
2014年

3

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

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

解决方案分为两部分。第一个是一个jquery脚本,它连接到jQuery ajax处理中。如果发出crossDomain请求并且浏览器是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/


1

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


2
只是对任何有此问题的人的注释-在这种情况下,如果您有<= IE7要求,并且您无法控制服务器(例如,不能使其支持JSON + GET +脚本标签),最好的选择是轻量级的中间件服务器,它将JSONP调用转换为POST,并将响应从黑匣子服务器流回给用户。
mikermcneil



0

为了解决此问题,还请检查您的ajax文件中是否包含一些包含.js的文件:我在ajax.php中包含shadowbox.js时收到访问拒绝错误。


0

我在我的开发机上测试了CORS Web服务,并且仅在IE中收到“访问被拒绝”错误消息。Firefox和Chrome正常运行。事实证明,这是由于我在ajax调用中使用了本地主机引起的!所以我的浏览器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 dev工具窗口的“网络”选项卡还显示了CORS Preflight OPTIONS请求,其后是XMLHttpRequest GET,这正是我期望看到的。




-1

注意-注意

不要在ajax中使用“ http://www.domain.xxx ”或“ http:// localhost / ”或“ IP >> 127.0.0.1”作为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);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.