¿Por qué Internet Explorer no envía el cuerpo de la publicación HTTP en la llamada Ajax después de una falla?

114

Podemos recrear de manera confiable el siguiente escenario:

  1. Cree una pequeña página HTML que realice solicitudes AJAX a un servidor (usando HTTP POST)
  2. Desconectarse de la red y volver a conectarse
  3. Monitorear los paquetes que genera IE después de la falla

Después de una conexión de red fallida, IE realiza la siguiente solicitud AJAX pero solo envía el encabezado HTTP (no el cuerpo) cuando realiza la publicación HTTP. Esto causa todo tipo de problemas en el servidor, ya que es solo una solicitud parcial. Busque en Google este problema con Bing y encontrará muchas personas que se quejan de "errores aleatorios del servidor" utilizando AJAX o fallas inexplicables de AJAX.

Sabemos que IE (a diferencia de la mayoría de los otros navegadores) siempre envía un HTTP POST como DOS paquetes TCP / IP. El encabezado y el cuerpo se envían por separado. En el caso directamente después de una falla, IE solo envía el encabezado . IE nunca envía la carga útil y el servidor finalmente responde con un tiempo de espera.

Entonces mi pregunta es: ¿por qué se comporta de esta manera? Parece incorrecto según la especificación HTTP y otros navegadores no se comportan de esta manera. ¿Es simplemente un error? Seguramente esto crea estragos en cualquier aplicación web seria basada en AJAX.

Informacion de referencia:

Existe un problema similar, desencadenado por tiempos de espera de HTTP Keep-Alive que son inferiores a 1 minuto y se documenta aquí:

http://us.generation-nt.com/xmlhttprequest-post-sometimes-fails-when-server-using-keep-aliv-help-188813541.html

http://support.microsoft.com/default.aspx?kbid=831167

Dodgyrabbit
fuente
6
Ésta es una pregunta excelente y bien definida que merece una respuesta. Desafortunadamente, esto está un poco fuera de tema. No estoy seguro de si sería mejor en webmasters.stackexchange.com o superuser.stackexchange.com .
Stephen
3
@ gilly3, creo que algo debe estar mal conmigo, porque leí eso y solo asentía con la cabeza ...
Ryley
1
@ gilly3: cuando se traduzca al holandés, sería correcto, ya que 'googelen' es un verbo (incluso definido en el diccionario holandés) que significa 'buscar en la web' en holandés. Sí, se escribe "googelen" y no "googlen". Extraño, lo sé. Por lo tanto, podría simplemente decir: 'Googel dit probleem conoció a Bing'. y sería correcto.
11
@ gilly3: ¿Qué es Bing? Lo voy a buscar en Google.
Rocket Hazmat
5
"¿Por qué se comporta de esta manera?" - ¿Aceptaría usted como respuesta? "La gente de Microsoft, aunque en su mayor parte brillante, es parte de una cultura de programación fundamentalmente diferente de aquellos de nosotros que llegamos a la era digital a través de DEC, Unix, Apple, Commodore u otros orígenes, y tienden a hacer cosas que hacen que el resto de nosotros se quede sin aliento de asombro, no por su brillantez, sino por la complicación excesiva y la corrupción total de las cosas que son simples y directas para el resto de nosotros "?
jcomeau_ictx

Respuestas:

28

No parece haber una respuesta clara a esta pregunta, por lo que proporcionaré mis datos empíricos como sustituto y proporcionaré algunas formas de solucionarlo. Quizás algún conocedor de la EM algún día arroje algo de luz sobre esto ...

  1. Si HTTP Keep-Alive está deshabilitado en el servidor, este problema desaparece. En otras palabras, su servidor HTTP 1.1 responderá a cada solicitud Ajax con una Connection: Closelínea en la respuesta. Esto mantiene contento a IE, pero hace que cada solicitud de Ajax abra una nueva conexión. Esto puede tener un impacto significativo en el rendimiento, especialmente en redes de alta latencia.

  2. El problema se desencadena fácilmente si las solicitudes Ajax se realizan en rápida sucesión. Por ejemplo, hacemos solicitudes Ajax cada 100ms y luego cambia el estado de la red, el error es fácil de reproducir. Aunque la mayoría de las aplicaciones probablemente no realicen este tipo de solicitudes, es posible que tenga un par de llamadas al servidor una tras otra, lo que podría provocar este problema. Menos hablador mantiene feliz a IE.

  3. Sucede incluso sin autenticación NTLM.

  4. Ocurre cuando el tiempo de espera de HTTP Keep-Alive en el servidor es más corto que el predeterminado (que por defecto es de 60 segundos en Windows). Detalles proporcionados en el enlace en cuestión.

  5. No sucede con Chrome o Firefox. FF envía un paquete, por lo que parece evitar este problema por completo.

  6. Ocurre en IE 6, 7, 8. No se pudo reproducir con IE 9 beta.

Dodgyrabbit
fuente
4
¿Existen otras formas de solucionar este problema? ¿Alguna solución de javascript? Intenté mirar los diversos objetos XMLHTTP y todavía no solucionaron el problema.
Berlin Brown
11

El artículo de Microsoft KB titulado Cuando usa Microsoft Internet Explorer u otro programa para realizar una operación de re-POST, solo los datos del encabezado que se publican parece solucionar este problema.

El artículo proporciona una revisión. Para navegadores posteriores como IE8, dice que la revisión ya está incluida, pero debe habilitarse a través de la configuración del registro en la PC cliente.

Julian
fuente
1
Estoy experimentando este problema con IE10, que el artículo no menciona.
ClearCloud8
6
El artículo ahora menciona hasta IE11, por lo que parece que esto nunca se solucionó.
Peater
Creo que estoy experimentando este problema en un sitio de producción: los agentes de usuario asociados con el problema se corresponden con IE 8, 9, 10 y 11.
Millhouse
¿Alguien encontró una solución alternativa? Específicamente, envío un 307 y FF, Chrome, Safari vuelve a publicar los datos en el nuevo punto final; IE no. No puedo pedir a mis usuarios que realicen una revisión o un parche de registro.
Brad Gunn
2

Tuve un problema similar en el que algunas versiones anteriores de IE enviaban solo el encabezado y no el cuerpo de un POST. Mi problema resultó estar relacionado con IE y NTLM. Como no mencionó NTLM, esto probablemente no ayude, pero por si acaso:

http://support.microsoft.com/kb/251404

reensamblador
fuente
Su enlace fue útil para resolver un problema similar en IE 11 e IIS 6.
Harminder
1

Esto es una posibilidad remota, pero IE (e incluso Firefox) a veces "recuerda" la conexión que usa para una solicitud HTTP. Notas / ejemplos:

  • En Firefox, si cambio la configuración del proxy y presiono SHIFT-RELOAD en una página, todavía usa el proxy anterior. Sin embargo, si elimino el proxy anterior ("killall squid"), comienza a usar el nuevo proxy.

  • Cuando se desconecta / vuelve a conectar, ¿recibe una nueva dirección IP o algo similar? ¿Puede de alguna manera monitorear la antigua dirección IP para ver si IE está enviando datos a esa dirección ahora inactiva?

  • Supongo que IE está enviando los datos, simplemente por el camino equivocado. Puede que sea lo suficientemente inteligente como para no almacenar en caché las conexiones de red para los paquetes "POST", pero puede que no sea lo suficientemente inteligente como para hacer eso con las cargas útiles de POST.

  • Esto probablemente no afecta a la mayoría de las aplicaciones AJAX, ya que las personas rara vez se desconectan y vuelven a conectarse a sus redes.


fuente
2
Creo que el problema es el último. Creo que Microsoft usa una política de "rara vez sucede: no implementar". :)
1
Superviso todo el tráfico HTTP desde el origen al destino. Puedo confirmar que (a) mi dirección IP no cambió y (b) no hay ningún intento de enviar nada más. IE abre un nuevo socket y envía una solicitud parcial. La forma en que leí el artículo de MS es que una de sus actualizaciones de seguridad rompió IE. Luego crearon un parche para arreglar eso. Pero en caso de que quisiera que se comporte de la manera anterior "rota", puede agregar esta clave de registro. Retry_HeaderOnlyPOST_OnConnectionReset. Solo intento darle sentido a la locura.
Dodgyrabbit
En su último punto: si tiene una aplicación Ajax que sondea periódicamente, digamos 10 segundos, encontramos que si se deja abierta durante unas horas, este error ocurrirá invariablemente. Probablemente la conexión Wifi se cae o la red es incompleta, pero nuestra experiencia, este problema es muy real.
Dodgyrabbit
1

¿Utiliza la autenticación NTLM?

Cuando se usa la autenticación NTLM, IE no envía datos posteriores. Envía información de encabezado, espera una respuesta no autorizada, envía una autorización y, después de la 'reautenticación', envía la publicación.

EL MEJOR
fuente
No utilizamos la autenticación NTLM. Ocurre con solicitudes anónimas.
Dodgyrabbit
0

Hoy tuve un problema similar al usar $ .ajax y pude solucionarlo configurando async en falso.

$.ajax({
  async: false, 
  url: '[post action url]',
  data: $form.serialize(),
  type: 'POST',
  success: successCallback
});

robbie kouwenberg
fuente