2011-03-09 45 views
6

Estoy haciendo una solicitud de ajax desde un iframe que se inyecta en cada página mediante un complemento de IE. Estoy usando IE's cross domain request porque jQuery's ajax falla para IE. Esto funciona el 75% del tiempo en IE8 & 9. El otro 25%, el xdr.onload ni siquiera se dispara.Respuesta incoherente ajax (XDR) de IE

El servidor php está haciendo su trabajo ... el registro se ve igual cuando onload funciona y no se activa. Además, xdr.onerror tampoco se activa.

¿Alguna idea?

 thisURL = "http://example.com/getmsg.php?cmd=getMessage&iid=ddeb2c1228&uurl=http%3A%2F%2Fwww.cnn.com%2F&t=" + Math.random(); 

     // Use Microsoft XDR 
     var xdr = new XDomainRequest(); 
     xdr.open("GET", thisURL); 
     xdr.onload = function() { 
      // this is sometimes called, sometimes not in IE 
      alert('INCONSISTENT ALERT'); 
      callback(xdr.responseText); 
     }; 
     xdr.send(); 
+1

Solo una suposición aleatoria: podrías intentar agregar un parámetro sin sentido al final de la URL para asegurarte de que el navegador omite su caché ... Lo probaría yo mismo si me estuviera pasando a mí, pero es posible que no seas tan interesado en perder el tiempo en conjeturas completas :-) – Pointy

+1

... o simplemente use 'POST' que no se almacenará en caché en absoluto. Además, vincularía 'xdr.onerror =' para ver si se dispara. Desafortunadamente, no hay una descripción del error para los errores XDR. Además, asegúrese de que el encabezado '' Access-Control-Allow-Origin '' está configurado a '*' – jAndy

+0

@Point, t es en realidad math.random ... He editado mi respuesta. Es una buena suposición. Esto no se guarda en caché aunque – Kyle

Respuesta

4

enteraron de la edición de último minuto. En mi caso, necesitaba especificar un valor de tiempo de espera, aunque las solicitudes no se agotaban. Para depurar correctamente un problema de XDR, sugeriría el siguiente código, con cada alerta diciéndole qué está pasando con su código. Como dije, en mi caso era una declaración faltante timeout. Pero el código de abajo debe depurar cualquier problema XDR:

 var xdr = new XDomainRequest(); 
      if (xdr) { 
       xdr.onerror = function() { 
//     alert('xdr onerror'); 
       }; 
       xdr.ontimeout = function() { 
//     alert('xdr ontimeout'); 
       }; 
       xdr.onprogress = function() { 
//     alert("XDR onprogress"); 
//     alert("Got: " + xdr.responseText); 
       }; 
       xdr.onload = function() { 
//     alert('onload' + xdr.responseText); 
        callback(xdr.responseText); 
       }; 
       xdr.timeout = 5000; 
       xdr.open("get", thisURL); 
       xdr.send(); 
      } else { 
//    alert('failed to create xdr'); 
      } 
+1

Gracias, me perdí el tiempo de espera también, y parece tener un valor predeterminado de 0. –

+0

En caso de que ayude a alguien, acabo de luchar con las solicitudes X9 de IE9 para mi aplicación y encontré que parece que el tiempo de espera se restablece cuando llama al método open() (construyendo e inspeccionando manualmente un objeto XDomainRequest en la consola). Estaba obteniendo fallas aleatorias hasta que configuré el tiempo de espera después de llamar al método abierto. (Todavía lo tengo configurado de antemano en caso de que importe). – Andrew

0

Es difícil darle una respuesta definitiva aquí.

En primer lugar, debe intentar usar Fiddler para ver si se está produciendo una falla de red de algún tipo. Le ayudará a comprender si la solicitud se ha realizado realmente y la respuesta del servidor.

En segundo lugar, y no sé si esto aplica, recientemente tuvimos un problema con el dominio cruzado en IE. El código funcionó bien en otros navegadores: Firefox, Safari y Chrome. El problema en ese caso resultó que la solicitud devolvía un 404 que se esperaba. De todos modos, IE detuvo toda la ejecución en ese punto, incluso nuestro manejo de errores del evento 404 nunca se activó. Por lo tanto, podría obtener algo de lo mismo aquí. Firefox, Safari, etc. permiten que la secuencia de comandos continúe. Si devuelve un error, le recomendamos que lo devuelva con un valor de error.

+0

que probamos por falla de la red. no es eso. y no hay 404s devueltos. Todos los recursos se encuentran. – Kyle

0
  • En primer lugar, agregue un controlador onerror para depurar sus cosas. Regístrelos y vea qué sucede exactamente.
  • En segundo lugar, su enfoque 'math.random' es defectuoso. Una mejor opción es usar la nueva Fecha(). GetTime(), esto asegurará que tenga solicitudes únicas a medida que pase el tiempo.
  • tercer lugar, usted podría (probablemente debe) utilizar métodos POST para eludir IE obviamente estándares comportamiento basado (;-))
9

que estaba teniendo un problema muy similar: XDomainRequests no solamente una parte del tiempo, a pesar de Fiddler mostrando todas las cabeceras de petición y respuesta que se envían exactamente como era mi intención. Había definido cada controlador de eventos y la propiedad de tiempo de espera en estos objetos XDR, y no se llamaba a ninguno de los controladores. Las herramientas de desarrollador F12 mostraron las solicitudes como abortadas. Ambos GET y POST podrían anularse, en varios dominios diferentes, pero la primera solicitud siempre funcionó correctamente.

Luego he intentado poner las llamadas a xdr.send en un tiempo de espera, de esta manera:

setTimeout(function() { 
    xdr.send(); 
}, 0); 

y funcionó. No tengo idea de por qué, pero tal vez esto sea útil para otra persona.

7

Tiene razón al nombrar el título aquí. La experiencia es bastante inconsistente. Vamos a caminar a través de eso ...

var xdr, err, res, foo, url; 

xdr = new XDomainRequest(); 

err = function(){ alert("There was an error, operation aborted"); } 
res = function(){ alert("Success! " + xdr.responseText); } 
foo = function(){ return; } 

url = "http://hello.com/here/is/the/url/?query=true&whatever=asd"; 

xdr.onerror = err; 
xdr.ontimeout = foo; 
xdr.onprogress = foo; 
xdr.onload = res; 
xdr.timeout = 5000; 

xdr.open("get", url); 
xdr.send(null); 

El objeto XDomainRequest maneja de manera diferente en cada IE.

En IE9 -> el objeto XDomainRequest requiere que todos los identificadores tengan un método. Lo que significa que manejos como onerror, onload, ontimeout y onprogress tienen algo que hacer. Sin definir un método para estos identificadores, obtendrá una respuesta de red de "operación abortada".

En IE7/8/9 -> el XDomainRequest es ASYNC por defecto. Ejecutará el código más abajo en la pila independientemente del objeto xdr que complete o no. Poner un setTimeout puede ser una solución, pero no debería ser.

En este caso, active un evento y escuche el evento antes de ejecutar cualquier otro código. Un ejemplo de esto sería (en jQuery) ...

// call this method in xdr onload 
$(document).trigger("xdr_complete"); 

// use this wrapper in code you want to execute after the complete of xdr 
$(document).bind("xdr_complete", function(){ ... }); 

En IE7/IE8 usted notará que funcione. IE7 e IE8 son bastante "flojos" en cuanto a que no abortan cuando faltan métodos para los identificadores.

+0

No podía creerlo, pero establecer todas las devoluciones de llamadas me solucionó un problema. ¿Está esto documentado en alguna parte? –

Cuestiones relacionadas