RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Generalized AJAX Response Handling for XML Content

Making multiple simultaneous asynchronous requests in AJAX applications using the XmlHttpRequest object can be difficult, but this generalized XML response-handling code will help.

JAX is catching on, but handling multiple XML responses on the client side is difficult. Current methods of easing the hassle ignore important programming principles that are known to help avoid maintenance headaches down the road. This article presents an elegant method of handling any number of XML responses in an AJAX application, while adhering to the principles of abstraction and encapsulation.

The ability to asynchronously transfer XML documents between the client and server without refreshing the entire page opens up an entire field of possibilities for browser-based Web applications. Indeed, it changes the way you can and must think about Web applications, because new problems arise from asynchronous communications—especially when using the XMLHttpRequest and XMLHTTP objects. In this article, you'll explore some of these issues and develop an elegant method for handling them, all while adhering to important programming principles.

Abstraction and Asynchrony are Antagonists in AJAX
When AJAX makes a request, JavaScript calls a specified event-handling function when the readyState property of the XMLHttpRequest object changes. This event handler should check the properties of the request to see whether readyState has changed to 4 (completed) and whether the HTTP response status code is 200 (OK). Apple's developer site suggests the code below, which has become relatively standard. Note that this response-handling code depends on the properties and expected values of the XMLHttpRequest and XMLHTTP objects, because this will become important later.

   function processReqChanged() {
      // only if req shows "loaded"
      if (req.readyState == 4) {
         // only if "OK"
         if (req.status == 200) {
            // ...processing statements go here...
         } else {
            alert("There was an error.");

The preceding code does a fine job of handling a small number of response types.

What You Need
To gain the most benefit from this article, you should be comfortable with client-side JavaScript and have a general familiarity with XML and server-side scripting. Additionally, you should be familiar with the concept and implementation of AJAX techniques (see the links in the Related Resources section if you need a refresher). To run the downloadable sample code included with this article, you need an AJAX-capable Web browser, such as the latest version of Firefox, Mozilla, Opera, Konqueror, Safari, or Internet Explorer. You also need a Web server with PHP version 4 installed.

You have to check the response values because typically, Web requests via the XMLHttpRequest object to a server are asynchronous (although you can make synchronous requests, there's little reason to do so in Web applications). Bearing that in mind, consider the pseudo-code in Listing 2, which sends two requests. After sending the first request, the method immediately returns and execution continues on to send a second request in the subsequent lines.

   req = getNewReqInstance();

To demonstrate, assume the preceding code is for an application that checks for the availability of a domain name. The first server script (url1) checks the databases of other registrars, while the second script (url2) checks your local database. The local check operation is fast, while checking other registrars is comparatively slow. To increase the apparent speed of your application, you have split these tasks into two separate requests. That way, if the domain name is unavailable in your local database, the browser can report the fact immediately. On the other hand, if the domain is available in your database then you can display a message indicating that you're checking other registrars to confirm availability while the browser waits for a response from the remote database search.

When execution reaches the end of the preceding code fragment, the application has made two outstanding requests and is awaiting a response from each. But if you're using the processReqChanged function shown earlier for both requests, how can you determine which request the current response is associated with? In other words, because response handling is asynchronous and event-driven, and both the local and remote requests fire the processReqChanged method, how can you know whether the method was fired by the local or the remote call?

You could guess that the first response received will be from your local database and the response from the other registrars will take longer, because it must access many remote databases. However, trying to develop time-based rules to handle asynchronous processing is a losing battle. Your rule could break down if the local database is temporarily down and the connection timeout is larger than the time it takes the other request to process. Other less extreme cases could also cause the return order to change. In other words, you need to use something other than time to interpret the response; you need to think asynchronously.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date