2.3. Sending Asynchronous Requests
To make an asynchronous call, we need to accomplish two tasks: set the asynchronous flag on open to TRue, and add a readyStateChanged event handler. This event handler will wait for a ready state of 4, which means the response is loaded. It will then check the status property. If the status is 200, we can use responseText; if it's another value, we have an error, so we'll need to create an alert dialog to show it. An asynchronous call to test.php is shown in Listing 2-2. The initXMLHttpClient function from an earlier chapter section, "Cross-Browser XMLHttpRequest," is used to create our XMLHttpRequest object.
Listing 2-2. Making an Asynchronous Request
Although this code gets the job done, it's not a great long-term solution because we will have to write a new onreadystatechange method for each call. The solution to this is to create our own HttpClient class that wraps XMLHttpRequest. Such a class gives us an easy-to-use API and a property to use for the callback that has to deal only with successful requests. Just adding some helper methods would be a simpler solution, but that's not a possibility because IE doesn't allow you to add methods to an ActiveX object.
A sample XMLHttpRequest wrapper class is shown in Listing 2-3. The main features of the HttpClient class are a callback property that is called when a successful asynchronous request is complete and a makeRequest method that combines the open and send functions. It also provides event properties that are called when a request is made (onSend), when it ends (onload), and when an errors occurs (onError). A default onSend and onLoad implementation is provided, which creates a basic loading message while requests are being made.
Listing 2-3. HttpClient XMLHttpRequest Wrapper
The HttpClient class contains comments explaining its basic functionality, but you will want to look at a couple of areas in detail. The first areas are the properties you'll want to set while interacting with the class; these include the following:
Lines 1631 contain simple functions for handling some basic user feedback. When a request is sent to the server, a DOM element with the ID of HttpClientStatus is shown (lines 1619). When it completes, it is hidden again (lines 2326). The class also defines a function to call when an error happens (lines 2931); it creates an alert box with the error message. Common errors include receiving a 404 page not found HTTP error message or not being able to create an XMLHttpRequest object. The implementation of these three functions is simple, and you'll likely want to override them with more sophisticated application-specific versions.
Lines 3356 contain the init method, which is identical to the initXMLHttpClient function we created in Listing 2-1, except for what it does with its error message. Now it sends it to the onError method. You won't be dealing with this function directly because the makeRequest method will take care of it for you. The makeRequest method (lines 6279) is your main interaction with the class. It takes two parameters: a URL to which to make the request and a payload that is sent to the server if you're making a POST request. The actual implementation is a more generic version of the code shown in Listing 2-2. The _readyStateChangeCallback (lines 8299) method is set as the readyState handler by makeRequest. It handles calling onSend when the initial request is sent and then calling onload when the request completes. It also checks for a 200 HTTP status code and calls onError if some other status is returned.
Listing 2-4 uses the HttpClient class and shows its basic usage. A wrapper class like this helps cut down the amount of code you need to write per request while giving a single place to make future changes.
Listing 2-4. Using the HttpClient XMLHttpRequest Wrapper
Using the HttpClient XMLHttpRequest wrapper is a simple task. You start by including it in the header of your HTML page (line 5), and then you can proceed to use it. You do this by creating an instance of the class (line 9), configuring its basic properties (in this case, setting isAsync to true (line 10)), and then setting up some code to call makeRequest. In most cases, this code will be contained in a function so that it can be tied to a user-driven event, such as clicking a link. The call is made by the test function (lines 1217); the test function first sets up a callback to run when the request is complete (lines 1315), and then it calls makeRequest (line 16), which starts the AJAX call.