Jquery $ .ajax falla en IE en llamadas de dominio cruzado

Estoy haciendo una solicitud de dominio cruzado usando $.ajax . Funciona en Firefox y Chrome, pero no emite una llamada en IE 7 u 8. ¿Puede alguien decirme qué pasa con lo siguiente?

  1. He usado JSON y JSONP (que dejé de usar, debido a algunas restricciones personalizadas).
  2. Ya estoy usando el encabezado Allow-access-control-origin en mi sitio. (Sin ellos, Chrome y Firefox no realizaban solicitudes exitosas).
  3. Ya lo he intentado https://developer.mozilla.org/es/http_access_control

Código:

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

He intentado varios consejos presentes en varios sitios, pero aún no tengo suerte.

¿Podría verificar si el problema con IE depende de no definir las zonas de seguridad para permitir solicitudes de dominios cruzados? Consulte esta página de microsoft para obtener una explicación.

OTOH, esta página menciona que IE7 y eariler no pueden hacer llamadas de dominio cruzado, pero IE8 puede, usando un objeto diferente de XMLHttpRequest, el que usa JQuery. ¿Podría verificar si XDomainRequest funciona?

EDITAR (2013-08-22)

El segundo enlace está muerto, así que estoy escribiendo aquí parte de su información, tomada de la máquina de retorno :

XDomainRequest soportado: IE8

En lugar de implementar la versión CORS de XMLHttpRequest, el equipo de IE se ha ido con su propio objeto de propiedad, llamado XDomainRequest. El uso de XDomainRequest se ha simplificado desde XMLHttpRequest, al tener más eventos lanzados (con onload quizás sea el más importante).

Esta implementación tiene algunas limitaciones asociadas. Por ejemplo, las cookies no se envían al usar este objeto, lo que puede ser un dolor de cabeza para las sesiones basadas en cookies en el lado del servidor. Además, ContentType no se puede configurar, lo que plantea un problema en ASP.NET y posiblemente en otros idiomas del lado del servidor (consulte 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(); 

Para IE8 e IE9 necesita usar XDomainRequest (XDR). Si miras a continuación, verás que está en una especie de formato similar a $ .ajax. En lo que respecta a mi investigación, no puedo lograr que este dominio cruzado trabaje en IE6 y 7 (aún estoy buscando una solución alternativa para esto). XDR apareció por primera vez en IE8 (también está en IE9). Entonces, básicamente, primero, pruebo el 6/7 y no hago AJAX.

IE10 + es capaz de hacer dominios cruzados normalmente como todos los otros navegadores (felicidades Microsoft … suspiro)

Después de eso, el otro si prueba para ‘XDomainRequest en la ventana (aparentemente mejor que el rastreo del navegador) y lo hace la solicitud JSON AJAX de esa manera, de otro modo el ELSE lo hace normalmente con $ .ajax.

¡¡Espero que esto ayude!! Me tomó para siempre para obtener todo esto resuelto originalmente

Información sobre el objeto 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 hace esto por ti, lo único es establecer $.support.cors = true; Entonces la solicitud de dominio cruzado funciona bien en todos los navegadores para usuarios de jquery.

Simplemente instale este complemento jQuery: jQuery Cross-Domain AJAX para IE8

Este complemento de 1.4kb funciona de inmediato en Internet Explorer 8 y 9 .

Incluye el complemento después de jQuery y llama a tu solicitud de ajax como siempre. Nada más requerido.

  • Plugin GitHub repo e instrucciones de instalación

Agregue transporte adicional a jquery para IE. (Simplemente agregue este código en su script al final)

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

Esto resolvió mi problema con Jquery $ .ajax al fallar en la solicitud AJAX de Cross Domain.

Aclamaciones.

Otros que vienen aquí pueden leer http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx, que habla sobre las limitaciones de XDomainRequest.

Para cualquiera que todavía tenga este problema usando jQuery 2.0 (sé que lo hago), Jay Dave escribió la mejor solución de jQuery, pero aún tengo algunas cosas que agregar a su código, a saber:

  • asegúrese de estar utilizando el mismo protocolo para las solicitudes (HTTP -> HTTP o HTTPS -> HTTPS), Ayush Gupta dio un enlace a los problemas conocidos
  • manejar los eventos “onprogress” con una función no operativa (esto evitará que IE ejecute las solicitudes una vez que reciba los primeros bits del servidor).

El código completo está a continuación:

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

Simplemente agregue “? Callback =?” (o “& callback =?”) a su url:

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

Al hacer las llamadas (con todo lo demás configurado correctamente para dominios cruzados, como se indicó anteriormente), esto activará el formateo JSONP correcto.

Se puede encontrar una explicación más detallada en la respuesta aquí .

@Furqan ¿Podría decirme si ha probado esto con el método HTTP POST,

Como también estoy trabajando en el mismo tipo de situación, pero no puedo enviar los datos a diferentes dominios.

Pero después de leer esto fue bastante simple … lo único es que tienes que olvidarte de navegadores OLD. Estoy dando código para enviar con el método POST desde la misma URL anterior para una referencia rápida

 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, agregando

 $.support.cors = true; 

fue suficiente para forzar llamadas $ .ajax para trabajar en IE8

Microsoft siempre es un surco contraproducente (al menos en IE):

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

CORS funciona con XDomainRequest en IE8. Pero IE 8 no es compatible con las Solicitudes Preflighted o Credentialed, mientras que Firefox 3.5+, Safari 4+ y Chrome son compatibles con dichas solicitudes.

Tengo el mismo problema en IE, lo resolví reemplazando:

  

A

  

Así que, básicamente, actualice su versión de jquery.

Tuve un problema similar en IE9, donde algunas llamadas CORS abortaban, mientras que otras no. Mi aplicación también depende de una interfaz prometedora, por lo que las sugerencias de XDomainRequest anteriores no eran EXACTAMENTE lo que necesitaba, así que agregué una solución diferida en mi service.get para IE9. Con suerte, puede ser útil para alguien más que se encuentre con este 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 }); } } 

Es difícil de decir debido a la falta de formato en la pregunta, pero creo que veo dos problemas con la llamada ajax.

1) la aplicación / x-www-form-urlencoded para contentType debe estar entre comillas

2) Debe haber una coma que separe los parámetros contentType y async.