Make the XMLHttpRequest Object Work Cross-Browser : Page 2

Microsoft invented the XMLHttpRequest object for Internet Explorer, but it's now supported in Safari, Opera and Mozilla browsers, although the underlying implementation is different. Still, the interfaces are similar enough thatwith a little effortyou can use the XMLHttpRequest object to exchange data with servers, no matter which browser is running.

by Nigel McFarlane

Aug 16, 2005

Page 2 of 3

Introducing XMLHttpRequest
The XMLHttpRequest object is a JavaScript (ECMAScript) host object, meaning that it exposes features of the JavaScript interpreter's host (the Web browser) to scripts. It's similar to the Image and Option objects, in that you create instances of it using the JavaScript new operator. It's different in that it's not ever contained in any HTML or XML document; instead, it's a bit of the browser's own internal plumbing that's exposed to the Web page's scripting environment. You can think of it as similar to the document.cookie property, which provides an access point to the browser's internal database of cookies.

Here's a bit of code that shows how to use this objectI'll cover what's portable and what's not in the remainder of this article. All browsers except Microsoft's Internet Explorer follow the Mozilla implementation (which nearly adheres to the original IE implementation), so I'll use the Mozilla syntax as a starting point, and show you IE-specific code later. To whet your appetite, here's a basic JavaScript form submission:

The preceding code sends the values of two <input type="text"> form fields (name="fieldA" and name="fieldB") to the server. First it collects the data from the HTML form. Next, it packs the data into the correct form-encoded string. The encodeURI() method is the fancy modern equivalent of the trusty escape() method, so the code uses that.

The browser performs that encoding automatically in a non-scripted (standard) form submit process, but for a scripted version, you have to remember to escape the data yourself.

So far, the code is all plain JavaScript and pretty simple. But then, it assigns a special XMLHttpRequest instance object to the request variable.

var request = new XMLHttpRequest();

That's new. When the script calls the open() method, the object composes the HTTP header for the request, so all that's left to do is send off the data, using send().

request.open("POST", "post_handler.cgi");
request.send(params);

When the send method returns, the request object is filled with whatever data and headers the server sent back in the HTTP response. Simple! In this case the script checks that the response code indicated success (but all 200-series return codes technically indicate success, so we could be more thorough), then digs out a header, and displays it for the user by writing it into one of the form fields already visible on the page.

Now for the gory bits. Technically, this request object is a network proxy object, and follows the Half Sync/Half-Async design pattern (if you believe in such things). You can read the theoretical details here, http://www.cs.wustl.edu/~schmidt/PDF/PLoP-95.pdf, but the practical explanation is that the object acts as a network endpoint. If you put in true as a third argument to open(), the request will proceed (roughly) as though it were sent with this line:

setTimeout("request.send(params)",0);

In other words, the third argument therefore determines whether JavaScript execution halts while runs. If it does, that's a delay (potentially a long one) for the user. If it doesn't, the UI won't freeze up, but you must install an event handler on the request object so that you can find out when the request completes. You assign such a handler to the request object before calling send(), using code such as this:

The script assigns the response_handler() function to the onload event of the request (XmlHttpRequest) object; therefore the response_handler() function runs when the object receives its data from the server in response to the request. This sample code doesn't do much with the return data, but that data could be a script, an XML fragment, plain text (character data), or anything else. The data exists as a property of the request object until you do something with it, such as storing it in a JavaScript variable or inserting it into the DOM for the currently loaded page. The important point to remember is that it's ultimately just data; it's not "special" in any way.

You can construct either a GET or POST request, and you can send that request synchronously (the default) or asynchronously, by passing true as the third parameter to the open() method.

So, now that you've seen the basics of how the XMLHttpRequest object works, you need to remain aware that the implementations differ between Internet Explorer and other modern browsers.