Friday, March 18, 2005

XMLHTTP and readyState

Given how the world of web design is currently enamored with Ajax — a.k.a. Asynchronous JavaScript + XML, a.k.a. remote scripting with XML messages, a.k.a. a technology that back in 2000 was considered way too rawk star and subversive until Google started playing with it recently — I thought I'd unearth this oldie-but-goodie from 2002. Enjoy.

Microsoft's XMLHTTP object is an ActiveX component that lets you perform HTTP requests. The object has four different states that it cycles through when performing a request. One of those states is called "interactive" and is decribed as such (from the MSDN documentation):

Some data has been received. You can call responseBody and responseText to get the current partial results.

...meaning that at that point you should be able to examine the contents of the response so far. Let's try this, shall we?

var xmlHTTP = new ActiveXObject("Microsoft.XMLHTTP");
xmlHTTP.onreadystatechange = handleStateChange;

function handleStateChange()
    if (xmlHTTP.readyState == 3)

Execution of this code produces an error in the handler:

The data necessary to complete this operation is not yet available.

...which troubles me greatly. Waiting until readyState is 4 (complete) works perfectly, but there's an added complication: the URI /some/uri establishes a persistent connection, which means that unless the connection is terminated by the script or the server, readyState will always be 3 (interactive). According to the docs, I should be able grab the incomplete response from the server at this time, but apparently not. Possible reasons:

  • the MSDN documentation is a big fat lie incorrect
  • the XMLHTTP object has a huge buffer to fill before it will make the response available
  • the object needs to see some sort of delimiter, like a null byte, as a signal to make the response text available
  • I'm horribly misunderstanding the whole thing

UPDATE 3/4/2004: many. many people have written me to ask if I have found a workaround since I first posted this. I'm sorry to say that I have not.


At 12:42 PM, Anonymous Anonymous said...

the documentation for XMLHTTP clearly states that, in the interactive state, the responseBody and responseText properties will return an error because status and response headers are not fully available. Do do async reads, you need to use the DOMDocument object. You can handle the ondataavailable event to tell when you have new content available to read.

At 9:01 AM, Blogger Sam-I-Am said...

Go on... Mr/Ms anonymous, this very problem is one of my open bugs and you seem to be in possesion of the fix. Can you spell it out a bit? An example? Do you mean use the DOMDocument object vs. the XmlHttpRequest object?

Are you also saying that if I simply ignore all but the complete ready response I don't need to worry about it?

At 8:36 AM, Blogger Lost in the World said...

After much testing, I've proved that although the XMLHTTP returns a responseStream, the data is only available (even in IStream format) once the XMLHTTP.readyState = 4, which is when the data has been fully populated. (as per tom trenka's comment)

This almost makes the IStream interface from the XMLHTTP object pointless.

As I was ultimately trying to load a SAXXMLReader data with a stream from a URL, I did a bit of a work around and managed to use the SAXXMLReader.parseURL. This loads a xml stream far better. (once it's large buffer has been filled)

At 5:51 AM, Blogger HiiFii Webservices said...

I liked you Blog so much,so i also wanted to show you some good resourses on the net.
Learn to earn 90000$/Month
For which you may also see my Personal Website
and for a Personal Education Career Tools
free Study Database.
This site is for seeing the
Hifi Electronics.
And this is for
World Class Gadgets


Post a Comment

<< Home