Jquery $ .ajax non riesce in IE su chiamate interdominio

Sto facendo una richiesta di dominio incrociato usando $.ajax . Funziona su Firefox e Chrome, ma non emette una chiamata su IE 7 o 8. Qualcuno può dirmi cosa c’è di sbagliato in quanto segue?

  1. Ho usato JSON e JSONP (che ho smesso di usare, a causa di alcune restrizioni personalizzate).
  2. Sto già usando l’intestazione Allow-access-control-origin sul mio sito. (Senza quelli, Chrome e Firefox non stavano facendo richieste di successo.)
  3. Ho già provato https://developer.mozilla.org/en/http_access_control

Codice:

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

Ho provato vari suggerimenti presenti su più siti, ma ancora senza fortuna.

Potresti verificare se il problema con IE si basa sulla non definizione delle zone di sicurezza per consentire le richieste cross-domain? Vedi questa pagina di Microsoft per una spiegazione.

OTOH, questa pagina menziona che IE7 e eariler non possono effettuare chiamate interdominio, ma IE8 può, usando un object diverso da XMLHttpRequest, quello utilizzato da JQuery. Potresti controllare se XDomainRequest funziona?

EDIT (2013-08-22)

Il secondo link è morto, quindi sto scrivendo qui alcune delle sue informazioni, prese dalla macchina del wayback :

XDomainRequest Supportato: IE8

Piuttosto che implementare la versione CORS di XMLHttpRequest, il team di IE è andato con il proprio object di proprietà, chiamato XDomainRequest. L’uso di XDomainRequest è stato semplificato da XMLHttpRequest, con più eventi lanciati (con onload forse il più importante).

Questa implementazione ha alcune limitazioni ad essa collegate. Ad esempio, i cookie non vengono inviati quando si utilizza questo object, che può essere un mal di testa per le sessioni basate sui cookie sul lato server. Inoltre, ContentType non può essere impostato, il che pone un problema in ASP.NET e probabilmente in altri linguaggi lato server (vedere 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(); 

Per IE8 e IE9 è necessario utilizzare XDomainRequest (XDR). Se guardi sotto vedrai che è in una sorta di formattazione simile a $ .ajax. Per quanto riguarda la mia ricerca, non riesco a ottenere questo cross-domain funzionante in IE6 e 7 (ancora in cerca di un work-around per questo). XDR è uscito per la prima volta in IE8 (anche in IE9). Quindi, in pratica, per prima cosa, eseguo il test per 6/7 e non faccio AJAX.

IE10 + è in grado di fare cross-domain normalmente come tutti gli altri browser (congratulazioni Microsoft … sigh)

Dopodiché il else if test per ‘XDomainRequest nella finestra (apparentemente migliore dello sniffing del browser) e fa la richiesta JSON AJAX in questo modo, altrimenti l’ELSE lo fa normalmente con $ .ajax.

Spero che questo ti aiuti!! Mi ci sono voluti per sempre per capire tutto in origine

Informazioni sull’object 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); } }); } } 

Jquery fa questo per te, l’unica cosa è impostare $.support.cors = true; Quindi la richiesta cross domain funziona correttamente su tutti i browser per gli utenti jquery.

Basta installare questo plugin jQuery: jQuery Cross-Domain AJAX per IE8

Questo plugin 1.4kb funziona subito con Internet Explorer 8 e 9 .

Includere il plug-in dopo jQuery e chiamare la richiesta ajax come di consueto. Nient’altro richiesto.

  • Plugin GitHub repo e installare le istruzioni

Aggiungi trasporto extra a jquery per IE. (Basta aggiungere questo codice nel tuo script alla fine)

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

Questo ha risolto il mio problema con Jquery $ .ajax in mancanza della richiesta AJAX di Cross Domain.

Saluti.

Gli altri che arrivano qui potrebbero fare bene a leggere http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx che parla dei limiti di XDomainRequest

Per chiunque possa ancora avere questo problema usando jQuery 2.0 (lo so che faccio), Jay Dave ha scritto la migliore soluzione di jQuery ma ho ancora alcune cose da aggiungere al suo codice e cioè:

  • assicurati di utilizzare lo stesso protocollo per le richieste (HTTP -> HTTP o HTTPS -> HTTPS), Ayush Gupta ha fornito un link per conoscere i problemi
  • gestire gli eventi “onprogress” con una funzione no-op (ciò impedirà a IE di soddisfare le richieste dopo aver ricevuto i primi bit dal server.

Il codice completo è qui sotto:

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

Basta aggiungere “? Callback =?” (o “& callback =?”) al tuo url:

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

Quando esegui le chiamate (con tutto il resto impostato correttamente per il dominio incrociato, come sopra) questo attiverà la corretta formattazione JSONP.

Qui puoi trovare una spiegazione più approfondita nella risposta.

@Furqan Potrebbe farmi sapere se hai provato questo con il metodo HTTP POST,

Dal momento che sto anche lavorando sullo stesso tipo di situazione, ma non sono in grado di inviare i dati a domini diversi.

Ma dopo aver letto questo è stato abbastanza semplice … l’unica cosa è che devi dimenticare i browser OLD. Sto dando il codice da inviare con il metodo POST dallo stesso URL sopra per una rapida consultazione

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

Nota, aggiungendo

 $.support.cors = true; 

è stato sufficiente per forzare le chiamate $ .ajax a lavorare su IE8

Microsoft solleva sempre un solco autodistruttivo (almeno in IE):

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

CORS funziona con XDomainRequest in IE8. Ma IE 8 non supporta le richieste preflight o credenziali mentre Firefox 3.5+, Safari 4+ e Chrome supportano tutte queste richieste.

Ho lo stesso problema in IE, l’ho risolto sostituendo:

  

A

  

Quindi sostanzialmente aggiorna la tua versione jquery.

Ho avuto un problema simile in IE9, dove alcune chiamate CORS stavano interrompendo, mentre altre no. La mia app dipende anche da un’interfaccia di promise, quindi i suggerimenti di XDomainRequest non erano ESATTAMENTE quelli di cui avevo bisogno, quindi ho aggiunto un rinviato alla mia soluzione di lavoro service.get per IE9. Spero che possa essere utile a qualcun altro che si imbatte in questo problema. :

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

È difficile da dire a causa della mancanza di formattazione nella domanda, ma penso di vedere due problemi con la chiamata ajax.

1) l’application / x-www-form-urlencoded per contentType deve essere tra virgolette

2) Dovrebbe esserci una virgola che separa i parametri contentType e async.