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

发布于 2024-09-12 16:12:04 字数 1312 浏览 7 评论 0原文

我正在使用 $.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

代码:

$.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);
    }
});

我已经尝试了多个网站上提供的各种提示,但还没有成功。

I am doing a cross domain request using $.ajax. It works on Firefox and Chrome, but does not issue a call on IE 7 or 8. Can anyone tell me what's wrong with the following?

  1. I have used JSON and JSONP (which I stopped using, due to some custom restrictions).
  2. I am already using Allow-access-control-origin header on my site. (Without those, Chrome and Firefox were not making successful requests.)
  3. I have already tried https://developer.mozilla.org/en/http_access_control

Code:

$.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);
    }
});

I have tried various tips present on multiple sites, but no luck yet.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

逆蝶 2024-09-19 16:12:04

对于 IE8 和IE9则需要使用XDomainRequest (XDR)。如果您看下面,您会发现它的格式与 $.ajax 类似。就我的研究而言,我无法让这个跨域在 IE6 和 IE6 中工作。 7(仍在寻找解决方法)。 XDR 首次出现在 IE8 中(IE9 中也有)。所以基本上首先,我测试 6/7 并且不执行 AJAX。

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

之后, else if 在窗口中测试“XDomainRequest”(显然比浏览器嗅探更好)并以这种方式执行 JSON AJAX 请求,其他明智的是,ELSE 通常使用 $.ajax 执行此操作。

希望这有帮助!我花了很长时间才弄清楚这一切

有关 XDomainRequest 的信息对象

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

For IE8 & IE9 you need to use XDomainRequest (XDR). If you look below you'll see it's in a sort of similar formatting as $.ajax. As far as my research has got me I can't get this cross-domain working in IE6 & 7 (still looking for a work-around for this). XDR first came out in IE8 (it's in IE9 also). So basically first, I test for 6/7 and do no AJAX.

IE10+ is able to do cross-domain normally like all the other browsers (congrats Microsoft... sigh)

After that the else if tests for 'XDomainRequest in window (apparently better than browser sniffing) and does the JSON AJAX request that way, other wise the ELSE does it normally with $.ajax.

Hope this helps!! Took me forever to get this all figured out originally

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);
            }
        });
    }
}
笑着哭最痛 2024-09-19 16:12:04

您能否检查一下 IE 的问题是否依赖于未定义安全区域以允许跨域请求? 请参阅此 Microsoft 页面以获取说明。

OTOH,此页面提到 IE7 eariler 不能进行跨域调用,但 IE8 可以,使用与 XMLHttpRequest(JQuery 使用的对象)不同的对象。您能检查一下 XDomainRequest 是否有效吗?

编辑(2013-08-22)

第二个链接已失效,所以我在这里写下它的一些信息,取自回程机

XDomainRequest
支持:IE8

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

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

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

Could you check if the problem with IE relies on not defining security zones to allow cross domain requests? See this microsoft page for an explanation.

OTOH, this page mentions that IE7 and eariler cannot do cross domain calls, but IE8 can, using a different object than XMLHttpRequest, the one JQuery uses. Could you check if XDomainRequest works?

EDIT (2013-08-22)

The second link is dead, so I'm writing here some of its information, taken from the wayback machine:

XDomainRequest
Supported: IE8

Rather than implement the CORS version of XMLHttpRequest, the IE team have gone with there own propriety object, named XDomainRequest. The usage of XDomainRequest has been simplified from XMLHttpRequest, by having more events thrown (with onload perhaps being the most important).

This implementation has a few limitations attached to it. For example, cookies are not sent when using this object, which can be a headache for cookie based sessions on the server side. Also, ContentType can not be set, which poses a problem in ASP.NET and possibly other server side languages (see 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();
长伴 2024-09-19 16:12:04

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

Jquery does this for you, only thing is to set $.support.cors = true; Then cross domain request works fine in all browsers for jquery users.

你好,陌生人 2024-09-19 16:12:04

只需安装此 jQuery 插件:适用于 IE8 的 jQuery 跨域 AJAX

这个 1.4kb 插件可以立即在 Internet Explorer 8 和 9 中运行。

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

Simply install this jQuery Plugin: jQuery Cross-Domain AJAX for IE8

This 1.4kb plugin works right away in Internet Explorer 8 and 9.

Include the plugin after jQuery, and call your ajax request as normal. Nothing else required.

坐在坟头思考人生 2024-09-19 16:12:04

向 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 请求失败的问题。

干杯。

Add extra transport to jquery for IE.
( Just add this code in your script at the end )

$.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();
          }
        };
      }
    });

This solved my problem with Jquery $.ajax failing for Cross Domain AJAX request.

Cheers.

南…巷孤猫 2024-09-19 16:12:04

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

Others coming around here might do well to read http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx which talks about limitations of XDomainRequest

北方。的韩爷 2024-09-19 16:12:04

对于使用 jQuery 2.0 可能仍然遇到此问题的人(我知道我确实如此),Jay Dave 编写了最好的 jQuery 解决方法,但我仍然需要在他的代码中添加一些内容,即:

  • 确保您对请求使用相同的协议( HTTP -> HTTP 或 HTTPS -> HTTPS),Ayush Gupta 提供了一个链接来了解如何
  • 使用无操作函数处理“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();
            }
        };
    });
}

For anyone whom might still have this problem using jQuery 2.0 (I know I do), Jay Dave wrote the best jQuery workaround but I still have a few things to add to his code namely:

  • make sure you are using the same protocol for requests (HTTP -> HTTP or HTTPS -> HTTPS), Ayush Gupta gave a link to knows issues
  • handle the "onprogress" events with a no-op function (this will prevent IE from abording the requests after it receives the first bits from the server.

The complete code is below:

// 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();
            }
        };
    });
}
幼儿园老大 2024-09-19 16:12:04

注意,添加

$.support.cors = true;

足以强制 $.ajax 调用在 IE8 上工作

Note, adding

$.support.cors = true;

was sufficient to force $.ajax calls to work on IE8

佞臣 2024-09-19 16:12:04

只需添加“?回调=?” (或“&callback=?”)到您的网址:

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

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

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

Simply add "?callback=?" (or "&callback=?") to your url:

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

When doing the calls (with everything else set properly for cross-domain, as above) this will trigger the proper JSONP formatting.

More in-depth explanation can be found in the answer here.

永言不败 2024-09-19 16:12:04

@Furqan能否请您告诉我您是否使用 HTTP POST 方法对此进行了测试,

因为我也在处理相同的情况,但我无法将数据 POST 到不同的域。

但阅读这个 这很简单......唯一的事情是你必须忘记旧的浏览器。我提供了使用上述 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);
}

@Furqan Could you please let me know whether you tested this with HTTP POST method,

Since I am also working on the same kind of situation, but I am not able to POST the data to different domain.

But after reading this it was quite simple...only thing is you have to forget about OLD browsers. I am giving code to send with POST method from same above URL for quick reference

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);
}
凉风有信 2024-09-19 16:12:04

微软总是弄巧成拙(至少在 IE 中):

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

CORS 与 IE8 中的 XDomainRequest 配合使用。但 IE 8 不支持预检或凭证请求,而 Firefox 3.5+、Safari 4+ 和 Chrome 都支持此类请求。

Microsoft always ploughs a self-defeating (at least in IE) furrow:

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

CORS works with XDomainRequest in IE8. But IE 8 does not support Preflighted or Credentialed Requests while Firefox 3.5+, Safari 4+, and Chrome all support such requests.

内心荒芜 2024-09-19 16:12:04

我在 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 版本。

I have the same problem in IE, I solved it by replacing:

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

To

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

So basically upgrade your jquery version.

-柠檬树下少年和吉他 2024-09-19 16:12:04

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

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

I had a similar problem in IE9 where some CORS calls were aborting, while others weren't. My app is also dependent on a promise interface, so the XDomainRequest suggestions above weren't EXACTLY what I needed, so I added a deferred into my service.get workaround for IE9. Hopefully it can be useful to someone else running across this problem. :

    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
            });
        }
    }
等往事风中吹 2024-09-19 16:12:04

由于问题中缺乏格式,很难说,但我认为 ajax 调用存在两个问题。

1) contentType 的 application/x-www-form-urlencoded 应该用引号引起来

2) 应该用逗号分隔 contentType 和异步参数。

It's hard to tell due to the lack of formatting in the question, but I think I see two issues with the ajax call.

1) the application/x-www-form-urlencoded for contentType should be in quotes

2) There should be a comma separating the contentType and async parameters.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文