from http://www.quirksmode.org/blog/archives/2005/09/xmlhttp_notes_r_2.html
As we all know an xmlhttp script requires the use of the readystatechange event. In theory, using the load event is also possible, but Explorer doesn’t support it on xmlhttp requests.
Both these events, and the readyState property, have a few odd quirks when used in an xmlhttp environment, though. These quirks don’t impact standard xmlhttp scripts too much, but as soon as you want to use the event objects or readyStates other than 4 you need to know about them.
readyState
The readystatechange event fires when the readyState of the request changes. This property can have four values, which theoretically work in the way shown below. In practice, though, the browsers don’t quite follow this de facto standard.
| 0 | Uninitialized – open() has not been called yet. |
| 1 | Loading – send() has not been called yet. |
| 2 | Loaded – send() has been called, headers and status are available. |
| 3 | Interactive – Downloading, responseText holds the partial data. |
| 4 | Completed – Finished with all operations. |
readyState 4 is equivalent to the load event and is a standard part of any xmlhttp script. I have never understood what the other three readyStates are good for; why would you need to know that responseText holds the partial data, for instance? One more mystery to solve.
That said, let’s try the following bit of script. You’d expect four alerts, 1, 2, 3 and 4.
xmlhttp.open("GET","somepage.xml",true);
xmlhttp.onreadystatechange = checkData;
xmlhttp.send(null);
function checkData()
{
alert(xmlhttp.readyState);
}
Results:
- Explorer: 1-2-3-4 (correct)
- Mozilla: 1-2-3-4 (correct)
- Safari: 2-3-4
- Opera: 3-4
Where have the missing readyStates gone in Safari and Opera? I have no idea.
Let’s move the event handler assignment to a different point in the code:
xmlhttp.onreadystatechange = checkData;
xmlhttp.open("GET","somepage.xml",true);
xmlhttp.send(null);
Results:
- Explorer: 1-1-2-3-4
- Mozilla: 1-1-2-3-4
- Safari: 1-2-3-4 (correct)
- Opera: 1-3-4
All browsers now add an extra readyState of 1 at the start of their sequence. Explorer and Mozilla give a “1″ alert twice, and that’s odd, because the event name is clearly readystatechange and a change from 1 to 1 is no change. Opera still lacks the readyState 2. Odd, odd.
Let’s move the event handler assignment again:
xmlhttp.open("GET","somepage.xml",true);
xmlhttp.send(null);
xmlhttp.onreadystatechange = checkData;
Explorer doesn’t react at all if you assign the readystatechange event after the send() method has been called.
- Explorer: nothing
- Mozilla: 2-3-4 (correct)
- Safari: 2-3-4 (correct)
- Opera: 3-4
In conclusion, no browser correctly supports readyState in all cases. Fortunately the all-important value of 4 is unaffected by this odd series of bugs.
readystatechange
Let’s consider the events themselves:
xmlhttp.open("GET","somepage.xml",true);
xmlhttp.onreadystatechange = checkData;
xmlhttp.send(null);
function checkData(e)
{
var evt = e || window.event;
var rs = xmlhttp.readyState || "None";
alert(evt.type + ' ' + rs);
}
Now you’d expect to get an alert “readystatechange 1″ through 4. Unfortunately only Safari gives this correct response, even though it starts at readyState 2, as we saw above.
- Explorer: “load 1″, then sometimes error messages, sometimes the “load 2″ through 4 you’d expect. Right now I think the error messages come when the XML document is being really loaded, and the 2 through 4 when Explorer can get the XML document from the cache.
- Mozilla: error message: event object doesn’t exist
- Safari: “readystatechange 2″ through 4
- Opera: error message: event object doesn’t exist
The readystatechange event object is entirely absent in Mozilla and Opera, while Explorer feels its type is a load event.
Another related point:
When you use synchronous loading in Mozilla (ie. browser waits until the XML file has been loaded before doing anything else), the readystatechange event is not available.
This is not a huge problem, because the idea behind synchronous loading is that you wait for the XML file to be available, anyway. The line after the xmlhttp.send(null) is executed only when the XML is there. Nonetheless this point should be noted, too.
load
Explorer has a point in so far as the load event can be seen as a subset of the readystatechange event. load fires when the page has been loaded completely, which is equivalent to saying the readyState is 4: completed.
Let’s try it:
xmlhttp.open("GET","somepage.xml",true);
xmlhttp.onload = checkData;
xmlhttp.send(null);
function checkData(e)
{
var evt = e || window.event;
var rs = xmlhttp.readyState || "None";
alert(evt.type + ' ' + rs);
}
- Explorer: error message because you assign the unknown property
onloadto the xmlhttp request - Mozilla: “load 4″
- Safari: “load 4″
- Opera: error message: event object doesn’t exist
So Explorer doesn’t support the load event on xmlhttprequests. We already knew this, but we should realize it doesn’t even allow you to set the event handler, since it allows only a very limited set of properties on the xmlhttp object.
The event object is still missing in Opera, though not in Mozilla.
