¿Puede XHR desencadenar onreadystatechange varias veces con readyState = DONE?

La especificación W3C sugiere la siguiente implementación: Un código simple para hacer algo con los datos de un documento XML captado a través de la networking:

function processData(data) { // taking care of data } function handler() { if(this.readyState == this.DONE) { if(this.status == 200 && this.responseXML != null && this.responseXML.getElementById('test').textContent) { // success! processData(this.responseXML.getElementById('test').textContent); return; } // something went wrong processData(null); } } var client = new XMLHttpRequest(); client.onreadystatechange = handler; client.open("GET", "unicorn.xml"); client.send(); 

¿Es esta implementación realmente correcta?

Durante la debugging encontré casos cuando el controller de events readystatechanged se llama más de una vez seguidas con el mismo valor de readyState == 4. Supongo que este comportamiento es correcto, ya que las especificaciones indican que cada cambio de estado debe desencadenar el evento y que readyState siempre debe ser igual al estado actual, por lo que si se acumulan varios events en la queue de events, es bastante obvio que uno recibirá múltiples llamadas con readyState == 4.

http://jsfiddle.net/44b3P/ – este es el ejemplo anterior aumentado con una llamada al depurador para detener la ejecución justo después de que se envíe la request, y con la alerta () en el processData. Una vez que haya reanudado la ejecución, recibirá 3 alertas.

Este ejemplo de w3c parece ser copydo y pegado en múltiples lugares en la web; en particular, OpenSocial parece manejar events xhr de esta manera. ¿Es correcto?

2 Solutions collect form web for “¿Puede XHR desencadenar onreadystatechange varias veces con readyState = DONE?”

También vi el mismo comportamiento (HECHO 200 golpeado más de una vez, es decir 2 … n veces) al depurar en Herramientas de desarrollo de Chrome.

Para hacer que funcione siempre en modo de debugging también, encontré dos opciones:

  1. Use onload para verificar el éxito de una XMLHTMLRequest W3C Spec

    client.onload = handler;

    Esta versión no funcionará en IE8. Debe ser un browser que implemente la interfaz XMLHttpRequestEventTarget

  2. Elimine el controller onreadystatechange tan pronto como tenga el estado DONE 200 .

     client.onreadystatechange = function() { // check if request is complete if (this.readyState == this.DONE) { if (this.onreadystatechange) { client.onreadystatechange = null; handler(); } } }; 

También abrí un problema en Chromium para este problema, proporcionando tu Fiddle (¡gracias!)

Nunca he tenido mi controller onreadystatechange ejecutado varias veces con un readyState de 4.

Creo que asumir una sola ejecución en DONE es correcta.

  • uso correcto de la XMLHttpRequest falsa de sinon
  • Pasar el valor de una function de carga xhr globalmente
  • Symfony2: permitir Access-Control-Allow-Origin con google charts
  • Abortar el xmlhttprequest
  • Solicitud HTTP HEAD en Javascript / Ajax?
  • Problemas con largas sondeos XMLHttpRequests y conexiones de networking intermitentes
  • Cómo cargar múltiples files en 1 request http
  • Número máximo de requestes http utilizando trabajadores web
  • ¿Cómo puedo enviar un object / matriz javascript como pares key-valor a través de una publicación de AJAX con easyXDM?
  • El método Http cambia de POST a OPCIONES al cambiar el tipo de contenido
  • Cómo especificar un website externo para XMLHTTPRequest
  • Javascript tiene muchos buenos JS marco (como Node.js AngularJS Vue.js React.js) es el mejor lenguaje de script.