在跨域调用的IE中,Jquery $ .ajax失败

时间:2010-07-29 12:35:18

标签: jquery cross-domain

我正在使用$.ajax进行跨域请求。它适用于Firefox和Chrome,但不会在IE 7或8上发出呼叫。任何人都可以告诉我以下内容有什么问题吗?

  1. 我使用过JSON和JSONP(由于一些自定义限制,我停止使用它)。
  2. 我已在我的网站上使用Allow-access-control-origin标题。 (没有这些,Chrome和Firefox没有成功请求。)
  3. 我已经尝试了https://developer.mozilla.org/en/http_access_control
  4. 代码:

    $.ajax({
        type: 'GET',
        url: "http://anotherdomain.com/Service/GetControl?id=" + zoneID,
        cache: false,
        contentType: "application/x-www-form-urlencoded",
        async: false,
        beforeSend: function (request) {
            //alert('before send');
            //request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
            //request.setRequestHeader("X-PINGOTHER", "pingpong");
        } ,
        success: function (data, status) {
            //alert("Data returned :" + data);
            //alert("Status :" + status);
            if (status == "success" && data != "")
                $("#" + div.id).append(data);
            else
                $("#" + div.id).attr("style", "display:none;");
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert(textStatus);
            alert(errorThrown);
        }
    });
    

    我在多个网站上尝试了各种提示,但还没有运气。

14 个答案:

答案 0 :(得分:61)

对于IE8& IE9你需要使用XDomainRequest(XDR)。如果你看下面,你会发现它的格式与$ .ajax类似。至于我的研究得到了我,我无法让这个跨域工作在IE6& 7(仍在为此寻找解决办法)。 XDR首先出现在IE8中(它也出现在IE9中)。所以基本上首先,我测试6/7并且不做AJAX。

IE10 +能够像所有其他浏览器一样正常进行跨域浏览(恭喜微软......叹息)

之后,如果在窗口中测试' XDomainRequest(显然比浏览器嗅探更好)并且以这种方式执行JSON AJAX请求,那么其他方面,ELSE通常会使用$ .ajax。

希望这有帮助!!永远地把我带到最初想出来的这个

Information on the XDomainRequest object

// call with your url (with parameters) 
// 2nd param is your callback function (which will be passed the json DATA back)

crossDomainAjax('http://www.somecrossdomaincall.com/?blah=123', function (data) {
    // success logic
});

function crossDomainAjax (url, successCallback) {

    // IE8 & 9 only Cross domain JSON GET request
    if ('XDomainRequest' in window && window.XDomainRequest !== null) {

        var xdr = new XDomainRequest(); // Use Microsoft XDR
        xdr.open('get', url);
        xdr.onload = function () {
            var dom  = new ActiveXObject('Microsoft.XMLDOM'),
                JSON = $.parseJSON(xdr.responseText);

            dom.async = false;

            if (JSON == null || typeof (JSON) == 'undefined') {
                JSON = $.parseJSON(data.firstChild.textContent);
            }

            successCallback(JSON); // internal function
        };

        xdr.onerror = function() {
            _result = false;  
        };

        xdr.send();
    } 

    // IE7 and lower can't do cross domain
    else if (navigator.userAgent.indexOf('MSIE') != -1 &&
             parseInt(navigator.userAgent.match(/MSIE ([\d.]+)/)[1], 10) < 8) {
       return false;
    }    

    // Do normal jQuery AJAX for everything else          
    else {
        $.ajax({
            url: url,
            cache: false,
            dataType: 'json',
            type: 'GET',
            async: false, // must be set to false
            success: function (data, success) {
                successCallback(data);
            }
        });
    }
}

答案 1 :(得分:32)

您能否检查IE的问题是否依赖于不定义安全区域以允许跨域请求? See this microsoft page获得解释。

OTOH,this page提到IE7和eariler不能进行跨域调用,但是IE8可以使用与XMLHttpRequest不同的对象来使用JQuery。你能检查XDomainRequest是否有效吗?

编辑(2013-08-22)

第二个链接已经死了,所以我在这里写一些信息,取自wayback machine

  

XDomainRequest   支持:IE8

     

IE团队没有实现XMLHttpRequest的CORS版本,而是使用了自己的专有对象,名为XDomainRequest。通过抛出更多事件(onload可能是最重要的),XMLHttpRequest简化了XDomainRequest的使用。

     

此实现有一些限制。例如,使用此对象时不会发送cookie,这可能是服务器端基于cookie的会话的头痛问题。此外,无法设置ContentType,这在ASP.NET和其他服务器端语言中可能会出现问题(请参阅http://www.actionmonitor.co.uk/NewsItem.aspx?id=5)。

var xdr = new XDomainRequest();
xdr.onload = function() { alert("READY"); };
xdr.open("GET", "script.html");
xdr.send();

答案 2 :(得分:23)

Jquery为你做这件事,唯一的事就是设置$.support.cors = true;然后跨域请求在jquery用户的所有浏览器中都能正常工作。

答案 3 :(得分:20)

只需安装此jQuery插件: jQuery Cross-Domain AJAX for IE8

此1.4kb插件可立即在 Internet Explorer 8和9 中使用。

在jQuery之后包含插件,并正常调用你的ajax请求。没有其他要求。

答案 4 :(得分:7)

为IE添加额外的传输到jquery。 (最后在脚本中添加此代码)

$.ajaxTransport("+*", function( options, originalOptions, jqXHR ) {

    if(jQuery.browser.msie && window.XDomainRequest) {

        var xdr;

        return {

            send: function( headers, completeCallback ) {

                // Use Microsoft XDR
                xdr = new XDomainRequest();

                xdr.open("get", options.url);

                xdr.onload = function() {

                    if(this.contentType.match(/\/xml/)){

                        var dom = new ActiveXObject("Microsoft.XMLDOM");
                        dom.async = false;
                        dom.loadXML(this.responseText);
                        completeCallback(200, "success", [dom]);

                    }else{

                        completeCallback(200, "success", [this.responseText]);

                    }

                };

                xdr.ontimeout = function(){
                    completeCallback(408, "error", ["The request timed out."]);
                };

                xdr.onerror = function(){
                    completeCallback(404, "error", ["The requested resource could not be found."]);
                };

                xdr.send();
          },
          abort: function() {
              if(xdr)xdr.abort();
          }
        };
      }
    });

这解决了我的问题,Jquery $ .ajax无法进行跨域AJAX请求。

干杯。

答案 5 :(得分:5)

其他人来到这里可能会很好地阅读http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx,其中讨论了XDomainRequest的限制

答案 6 :(得分:3)

对于那些使用jQuery 2.0可能仍然存在这个问题的人(我知道我这样做),Jay Dave编写了最好的jQuery解决方法,但我还有一些东西需要添加到他的代码中:

  • 确保您对请求使用相同的协议(HTTP - &gt; HTTP或HTTPS - &gt; HTTPS),Ayush Gupta提供了知道问题的链接
  • 使用no-op函数处理“onprogress”事件(这将阻止IE在从服务器接收到第一位后禁止请求。

完整的代码如下:

// add ajax transport method for cross domain requests when using IE9
if('XDomainRequest' in window && window.XDomainRequest !== null) {
   $.ajaxTransport("+*", function( options, originalOptions, jqXHR ) {
       // verify if we need to do a cross domain request
       // if not return so we don't break same domain requests
       if (typeof options.crossDomain === 'undefined' || !options.crossDomain) {
           return;
       }

        var xdr;

        return {
            send: function( headers, completeCallback ) {
                // Use Microsoft XDR
                xdr = new XDomainRequest();
                xdr.open("get", options.url); // NOTE: make sure protocols are the same otherwise this will fail silently
                xdr.onload = function() {
                    if(this.contentType.match(/\/xml/)){
                        var dom = new ActiveXObject("Microsoft.XMLDOM");
                        dom.async = false;
                        dom.loadXML(this.responseText);
                        completeCallback(200, "success", [dom]);
                    } else {
                        completeCallback(200, "success", [this.responseText]);
                    }
                };

                xdr.onprogress = function() {};

                xdr.ontimeout = function(){
                    completeCallback(408, "error", ["The request timed out."]);
                };

                xdr.onerror = function(){
                    completeCallback(404, "error", ["The requested resource could not be found."]);
                };

                xdr.send();
            },
            abort: function() {
                if(xdr) xdr.abort();
            }
        };
    });
}

答案 7 :(得分:2)

只需添加“?callback =?” (或“&amp; callback =?”)到你的网址:

$.getJSON({
    url:myUrl + "?callback=?",
    data: myData,
    success: function(data){
        /*My function stuff*/        
    }
});

在进行调用时(如上所述,其他所有内容都已正确设置为跨域),这将触发正确的JSONP格式化。

可以在答案here中找到更深入的解释。

答案 8 :(得分:1)

@Furqan您能告诉我您是否使用HTTP POST方法测试了这个,

由于我也在处理同样的情况,但我无法将数据发布到不同的域。

但在阅读this之后,这很简单......只有你必须忘记OLD浏览器。我正在使用上述URL上的POST方法发送代码以供快速参考

function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
    xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
    xhr = new XDomainRequest();
    xhr.open(method, url);
} else {
    xhr = null;
}
return xhr;
}

var request = createCORSRequest("POST", "http://www.sanshark.com/");
var content = "name=sandesh&lastname=daddi";
if (request){
    request.onload = function(){
    //do something with request.responseText
   alert(request.responseText);
};

 request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            request.setRequestHeader("Content-length", content.length);
            request.send(content);
}

答案 9 :(得分:1)

注意,添加

$.support.cors = true;

足以迫使$ .ajax调用在IE8上工作

答案 10 :(得分:0)

微软总是挫败自我挫败感(至少在IE中):

http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/

CORS适用于IE8中的XDomainRequest。但IE 8不支持Preflighted或Credentialed Requests,而Firefox 3.5 +,Safari 4+和Chrome都支持此类请求。

答案 11 :(得分:0)

我在IE中遇到同样的问题,我通过替换:

解决了这个问题
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

所以基本上升级你的jquery版本。

答案 12 :(得分:0)

我在IE9中遇到类似的问题,其中一些CORS调用正在中止,而其他调用则没有。我的应用程序也依赖于promise接口,因此上面的XDomainRequest建议并不完全是我所需要的,所以我在IE9中添加了一个延迟到我的service.get变通方法中。希望它对遇到这个问题的其他人有用。 :

    get: function (url) {
        if ('XDomainRequest' in window && window.XDomainRequest !== null) {
            var deferred = $.Deferred();
            var xdr      = new XDomainRequest();

            xdr.open("get", url);

            xdr.onload = function() {
              json = xdr.responseText;
              parsed_json = $.parseJSON(json);
              deferred.resolve(parsed_json);
            }

            xdr.send();
            return deferred;
        } else {
            return $.ajax({
                url: url,
                type: 'GET',
                dataType: 'json',
                crossDomain: true
            });
        }
    }

答案 13 :(得分:-1)

由于问题中没有格式化,很难分辨,但我认为我看到了ajax调用的两个问题。

1)contentType的application / x-www-form-urlencoded应该在引号中

2)应该有一个逗号分隔contentType和async参数。