The W3C spec suggest following implementation: Some simple code to do something with data from an XML document fetched over the network:
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();
Is this implementation really correct?
During debug I found cases when the readystatechanged event handler is called more than once in a row with the same value of readyState == 4. I guess this behavior is correct, as specs says that each change of state must fire the event, and that readyState must always be equal to current state, so if several events pile up in the events queue, it's quite obvious, that one will get multiple calls with readyState == 4.
/ -- this is the above example augmented with debugger call to pause execution just after the request is send, and with alert() in the processData. Once you unpause the execution you will get 3 alerts.
This example from w3c seems to be copy&pasted in multiple places in the web -- in particular OpenSocial seems to handle xhr events this way. Is it correct?
The W3C spec suggest following implementation: Some simple code to do something with data from an XML document fetched over the network:
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();
Is this implementation really correct?
During debug I found cases when the readystatechanged event handler is called more than once in a row with the same value of readyState == 4. I guess this behavior is correct, as specs says that each change of state must fire the event, and that readyState must always be equal to current state, so if several events pile up in the events queue, it's quite obvious, that one will get multiple calls with readyState == 4.
http://jsfiddle/44b3P/ -- this is the above example augmented with debugger call to pause execution just after the request is send, and with alert() in the processData. Once you unpause the execution you will get 3 alerts.
This example from w3c seems to be copy&pasted in multiple places in the web -- in particular OpenSocial seems to handle xhr events this way. Is it correct?
Share Improve this question edited Oct 7, 2012 at 9:11 qbolec asked Oct 6, 2012 at 15:49 qbolecqbolec 5,1342 gold badges37 silver badges45 bronze badges2 Answers
Reset to default 15I also saw the same behavior (DONE 200 being hit more than once, i.e. 2...n times) when debugging in Chrome Developer Tools.
To make it work always in debug mode as well, I found two options:
Use
onload
to verify the success of an XMLHTMLRequest W3C Specclient.onload = handler;
This version will not work in IE8. It must be a browser that implements the XMLHttpRequestEventTarget interface
Remove the
onreadystatechange
handler as soon as you have aDONE 200
state.client.onreadystatechange = function() { // check if request is plete if (this.readyState == this.DONE) { if (this.onreadystatechange) { client.onreadystatechange = null; handler(); } } };
I have also opened an issue in Chromium for this problem, providing your Fiddle (Thanks!)
I have never had my onreadystatechange
handler executed multiple times with a readyState
of 4.
I think assuming a single execution on DONE is correct.