2012-10-01 29 views
11

Tengo un sitio donde ingreso un nombre de usuario/contraseña y hago clic en un botón de inicio de sesión. El botón de inicio de sesión crea un objeto XMLHttpRequest y lo desactiva.La primera XMLHttpRequest falla pero solo en IE9

En Chrome, Firefox, Opera, Safari, dispositivos Android, dispositivos iOS, esto funciona bien. IE9 funcionará fin siempre que esté en una dirección HTTP y no use HTTPS.

En HTTPS, IE9 se comporta de la siguiente manera:

La primera solicitud de inicio de sesión no vuelve nunca nada a cambio. La pantalla F12 muestra mi solicitud de inicio de sesión en la pestaña de red y todo se ve correcto. La pestaña de scripts nunca arroja un error. Simplemente no pasa nada.

Aquí está la parte loca: - Si hago clic en iniciar sesión por segunda vez, en realidad funciona. - Si hago clic en actualizar en el navegador y luego inicio de sesión, ¡eso también funcionará!

Estoy creando la solicitud de la siguiente manera:

var x = new XMLHttpRequest(); 
    x.open("POST", "/Relative/URL/Path", true); 
    x.setRequestHeader("Content-Type", "text/plain"); 
    x.onreadystatechange = function() { 
     if ((x.readyState == 4) && (x.status == 200)) { 
      // handle callback 
     } 
    } 
    x.send(my request); 

Cuando esto falla, el depurador pasará de la línea x.send() en el código onreadystatechange. ReadyState será 1. Esta será la última vez que puedo depurar porque no ocurre nada más.

Cualquier idea sería muy apreciada.

[EDITAR]: Dejé una solicitud para ver qué pasaría. El evento onreadystatechange se disparó nuevamente con readyState = 4 y status = 12152. La vista de red en la pantalla F12 de IE9 muestra el resultado como Aborted y el tiempo tomado como 1589.07s. Una búsqueda en Google muestra que esto significa que la conexión se cerró en el servidor.

[EDIT 2]: Basado en un comentario a continuación Redirigí este código para usar simplemente el método ajax() de jQuery. Pensé que esto podría tener la oportunidad de eliminar el código malo de mi parte. No tal suerte. El mismo comportamiento ocurre.

$.ajax({ 
     "url": sUrl, 
     "success": function (data, textStatus, x) { 
     workerCallback(data, id, ""); 
     }, 
     "error": function (x, testStatus, errorThrown) { 
     workerCallback("nc", id, errorThrown); 
     }, 
     "contentType": "text/plain", 
     "data": JSON.stringify(req), 
     "dataType": "json", 
     "timeout": 1600000, 
     "type": "POST" 
    }); 

[ACTUALIZACIÓN FINAL:] He actualizado el código. Si se produce un tiempo de espera, simplemente vuelvo a publicar la misma solicitud, solo una vez. Todo el truco, pero funciona. A menos que alguien encuentre la solución, dividiré la recompensa entre algunas ideas útiles que la gente ha tenido a continuación.

+0

¿Está limpio el caché? ¿Usó algo como Fiddler para ver si las solicitudes se cancelan? – epascarello

+0

El caché está limpio. Gran sugerencia sobre el seguimiento de las solicitudes. Abrí WireShark (sniffer de red) y lo revisé. No puedo ver nada saliendo cuando hago clic en iniciar sesión la primera vez. ¡La segunda vez que veo las solicitudes! Pero IE dice que hizo la solicitud? – Paul

+0

Busque el código de error: http://support.microsoft.com/kb/193625 – epascarello

Respuesta

0

durante la depuración en la primera solicitud de este vino a través

enter image description here

Hay un puesto relacionado con este error exacto ... IE 9 Javascript error c00c023f

El autor puso el siguiente en el controlador onreadystatechange

if (xmlHttpRequest.aborted==true) { 
    stopLoadAnimation(); 
    return; 
} 

Esto puede ayudar a apuntar en la dirección correcta.

+0

Gracias por mirar, sin embargo, ese error no es en realidad un error. Ha depurado la primera vez que se establece ReadyState. En este caso, está configurado en 1 porque está a punto de realizar la llamada. La propiedad de estado no se establecerá aún, por lo que se intenta ver que en el depurador se producirá un error. Mi código comprueba el estado preparado y solo luego accede al estado y no arroja un error. – Paul

1

Esto parece un problema extraño y es difícil probarlo sin hurgar en el código de un sitio https.

Si desea una solución rápida, puede intentar hacer una solicitud inicial (ficticia) y luego cancelarla de inmediato con un breve setTimeout y realizar una segunda solicitud (real).

Según su descripción debería funcionar.

+0

Puede hojear el código. Lo publiqué todo en el enlace en la descripción de la recompensa. – Paul

+0

Aunque este es bastante el truco, actualicé el código en función de su comentario y de otro. Ahora, si ocurre un tiempo de espera, vuelvo a publicar la solicitud, solo una vez. Así que IE ahora tiene un largo retraso de inicio de sesión, sin embargo, funcionará al final. Si nadie tiene una respuesta exacta, dividiré la bondad entre usted y el otro. – Paul

+0

Sí, pero no tengo un servidor https para probarlo. No tiene que darle a IE un gran retraso. Anule primero una solicitud rápida y haga otra inmediatamente, y debería ser rápida en todas partes. – galambalazs

0
  • Timeouts impide que la solicitud sea terminado en readyState 1, y lo consigue después debido a la inhalación de contenido.

  • autenticación de cliente configurar SSL en el formulario de inicio de sesión utilizando la configuración del servidor web

  • Insertar un elemento oculto (como una imagen) que hace referencia a una dirección URL que requiere autenticación de cliente SSL

  • uso de un protocolo relativa hipervínculo gif, como //example.com/image.gif, para evitar la SEC7111 mixed content vulnerability

  • la URL de la open method coincide con el dominio cuando se utiliza HTTP, HTTPS, pero no, lo que hace la solicitud a fallan, pero las solicitudes posteriores caída al security zone policy

  • Utilice una comparación entre window.location.protocol y document.location.protocol para comprobar si la secuencia de comandos se ejecuta en el mismo contexto que la página

  • Envío de JSON como tipo MIME text/plain puede desencadenar content sniffing

  • comparar la Accept header entre las solicitudes que no frente a los que tienen éxito

  • HTTPS Caching puede ser un problema

  • El Connection header pueden necesitar ser establecido

    configuración
  • Proxy puede ser un problema

  • Los valores de respuesta initial header pueden ser demasiado grandes (por ejemplo, Descripción de estado HTTP tiene un límite de 512 caracteres)

  • document.readystate puede no ser completa en la solicitud inicial, lo que provoca premature execution problemas

  • Certificate revocation checks puedan bloquear el JSON mensaje inicial, pero permitirían solicitudes posteriores tras la devolución de llamada GET

  • readyState y de estado propiedades deben ser referenciados mediante el callback scope lugar de la variable x de evitar el uso del alcance de cierre:

 

    function cb() 
     { 
     if ((this.readyState === 4) && (this.status === 200)) 
     { 
     // handle callback 
     } 
     } 

    onreadystatechange = cb; 
+0

- Ya estoy usando un hipervínculo relativo. Solo recibí el problema de GIF una vez. - La URL abierta es relativa, por lo que debe coincidir con el dominio https. También utilicé la URL completa que apunta a https y aún falla. - Cuando falla, document.location.protocol y window.location.protocal coinciden perfectamente como https :. - Intenté enviar como "aplicación/json" pero esto no tuvo ningún efecto. - Una vez que cambié el código a $ .ajax(), no había ninguna referencia de 'x' necesaria para cambiar a 'esto'. Cambié esto el otro día. – Paul

+0

@Paul Sweatte - cambiar 'x' por' this' no cambiará nada porque se refieren a lo mismo. Aquí no hay ningún enganche porque es una '' FunctionExpression' * no una '' FunctionDeclaration' *, no creo que tenga la menor idea de lo que está hablando. Ver: http://kangax.github.com/nfe/ – galambalazs

+0

¿Está el botón de enviar dentro de un elemento de formulario? Si es así, puede haber una [condición de raza] (http://stackoverflow.com/questions/11449515/) o un [atributo de acción] problemático (http://stackoverflow.com/questions/1131781/). –

Cuestiones relacionadas