Peachpit Press

How To Use AJAX

Date: Nov 11, 2005

Return to the article

AJAX, an acronym for Asynchronous JavaScript and XML, is very hot in the growing universe of Web development. While this new technology offers some great capabilities, it also sparks some unquestionable debate over issues with the Back button. Kris Hadlock explains how to use AJAX in a real-world situation and how you can assess its value in a project. By the time you finish reading this article, you'll know what AJAX is as well as where, why, and how to use it.

Introduction

AJAX, an acronym for Asynchronous JavaScript and XML, is the latest technology buzzword. Asynchronous means that you can make a request to a server via Hypertext Transfer Protocol (HTTP) and continue to process other data while waiting for the response. This means, for example, that you can make calls to a server-side script to retrieve data from a database as XML, send data to a server-side script to be stored in a database, or simply load an XML file to populate pages of your Web site without refreshing the page. However, along with all of the benefits, AJAX sparks some unquestionable debate over issues with the Back button. This article will help you to determine when AJAX is a good solution for developing your users' experiences.

I'm assuming that you have a basic understanding of the JavaScript and XML part of the acronym. Although you can request any type of text file with AJAX, I'll focus strictly on XML. I'll explain how to use AJAX in a real-world situation and how you can assess its value in a project. By the time you finish reading this article, you'll know what AJAX is as well as where, why, and how to use it. You're going to learn how to create the object, make the request, and customize the response, while maintaining good practices that provide an intuitive user experience.

I've created a sample project for this article (you can download the source code). The sample is a simple request that loads an XML file containing page content and parses the data to display it in an HTML page.

Common Properties and Methods

Tables 1 and 2 provide an overview of the properties and methods supported by Windows Internet Explorer 5, Mozilla, Netscape 7, Safari 1.2, and Opera.

Table 1 Properties

Property

Description

onreadystatechange

Event handler that fires when the state of the request object changes.

readyState

Returns values that indicate the current state of the object.

responseText

String version of the response from the server.

responseXML

DOM-compatible document object of the response from the server.

status

Status code of the response from the server.

statusText

Status message returned as a string.

Table 2 Methods

Method

Description

Abort()

Cancels the current HTTP request.

getAllResponseHeaders()

Retrieves the values of all the HTTP headers.

getResponseHeader("headerLabel")

Retrieves the value of an HTTP header from the response body.

open("method", "URL"[, asyncFlag[, "userName"[, "password"]]])

Initializes an MSXML2.XMLHTTP request, specifying the method, URL, and authentication information for the request.

send(content)

Sends an HTTP request to the server and receives a response.

setRequestHeader("label", "value")

Specifies the name of an HTTP header.

Where To Start

First, you'll need to create the XML file that we will later request and parse as page content. The file that you're requesting must reside on the same server as the finished project.

Next, create the HTML file that will make the request. The request will happen when the page loads by using the onload method in the body tag. The file will then need a div tag with an ID so that we can target it when we're ready to display the content. When you've done all this, the body of your page should look like this:

<body onload="makeRequest('xml/content.xml');">
  <div id="copy"></div>
</body>

Creating the Request Object

To create the request object, you must check whether the browser uses the XMLHttpRequest or the ActiveXObject. The primary difference between the objects is the browsers that use them. Windows IE 5 and above use the ActiveX object; Mozilla, Netscape 7, Opera, and Safari 1.2 and above use the XMLHttpRequest object. Another difference is the way in which you create the objects: Opera, Mozilla, Netscape, and Safari allow you to simply call the objects' constructor, but Windows IE requires the name of the object to be passed to the ActiveX constructor. Following is an example of how to write the code to determine which object to use and how to create it:

if(window.XMLHttpRequest)
{
 request = new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
 request = new ActiveXObject("MSXML2.XMLHTTP");
}

Making the Request

Now that your request object has been created, you're ready to make a request to the server. Create a reference for an event handler to listen for onreadystatechange. The event handler method will then react when the state changes. We'll write this method as soon as we finish writing the request. Open the connection to GET or POST a custom URL, which in this case is the content.xml, and set a Boolean defining whether you want the call to be asynchronous.

It's time to send the request. In the example, I use null because we're using GET; to use POST, you would send a query string with this method:

request.onreadystatechange = onResponse;
request.open("GET". url, true);
request.send(null);

Custom Loading and Error Handling Messages

The event handler that you created for the onreadystatechange method is the place to focus on loading and error handling. This is the time to start thinking of the users and provide feedback about the status of the content with which they're interacting. In the example, I provide feedback for all the loading status codes and some basic feedback for the error handling status codes that occur most frequently. To indicate the current state of the request object, the readyState property includes the values shown in the following table.

Value

Description

0

Uninitialized. The object is not initialized with data.

1

Loading. The object is loading its data.

2

Loaded. The object has finished loading its data.

3

Interactive. The user can interact with the object even though it's not fully loaded.

4

Complete. The object is completely initialized.

The W3C has quite a long list of the HTTP status code definitions. I chose two status codes:

Finally, I check for any other status codes that would produce an error and provide a general error message. Following is an example of the code that you could use to handle these situations. Notice that I'm targeting the div ID that we created in the body of the HTML file and applying the loading and/or error messages to it with the innerHTML method, which sets the HTML between the start and end tags of the div object:

if(obj.readyState == 0)
{
 document.getElementById('copy').innerHTML = "Sending Request...";
}
if(obj.readyState == 1)
{
 document.getElementById('copy').innerHTML = "Loading Response...";
}
if(obj.readyState == 2)
{
 document.getElementById('copy').innerHTML = "Response Loaded...";
}
if(obj.readyState == 3)
{
 document.getElementById('copy').innerHTML = "Response Ready...";
}
if(obj.readyState == 4)
{
 if(obj.status == 200)
 {
  return true;
 }
 else if(obj.status == 404)
 {
  // Add a custom message or redirect the user to another page
  document.getElementById('copy').innerHTML = "File not found";
 }
 else
 {
  document.getElementById('copy').innerHTML = "There was a problem retrieving the XML.";
 }
}

When the status code is equal to 200, meaning that the request has succeeded, the response is ready to be parsed.

Parsing the Response

The real work begins when you're ready to parse the response from the request object. This is where you actually start working with the data that you requested. For testing purposes during development, the responseText and responseXML properties can be used to display the raw data from the response. To begin accessing nodes in the XML response, start with the request object that you created, target the responseXML property to retrieve (you guessed it) the XML from the response. Target the documentElement, which retrieves a reference to the root node of the XML response.

var response = request.responseXML.documentElement;

Now that you have a reference to the root node of the response, you can use getElementsByTagName() to retrieve childNodes by their node names. The following line locates a childNode with a nodeName of header:

response.getElementsByTagName('header')[0].firstChild.data;

Using firstChild.data allows you to access the text within the element:

response.getElementsByTagName('header')[0].firstChild.data;

Here's a complete example of how to write the code:

var response = request.responseXML.documentElement;
var header = response.getElementsByTagName('header')[0].firstChild.data;
document.getElementById('copy').innerHTML = header;

Assessing Your Needs

Now that you know the basics of how to use AJAX, deciding whether to use it on a project will certainly be the next step. The most important thing to keep in mind is that you can't use the Back button when you're not refreshing the page. Focus on smaller sections of your project that could benefit from using this type of interaction. For instance, you could build a form that queries a script every time a user enters an input field, or even types a letter in order to provide real-time validation. You could build a drag-and-drop page that sends data to a script on the release of an item and saves the state of the page to a database. The reasons for using AJAX definitely exist and are beneficial not only to the development experience but to users; it all depends on the situation and execution.

There are also ways to work around the issues with the Back button, such as with Google Gmail, which now provides an undo for steps that you make without refreshing the page. Many more creative examples are sure to surface, which will benefit users by providing developers with ways to create unique, real-time experiences.

Conclusion

Although AJAX allows us to build new and improved ways of interacting with a Web page, as developers we need to remember that the product is not about the technologies; it's about the users and how they interact with the product. Without the users, the projects we build would have no purpose. With that principle in mind, we can assess what technologies to use and when to use them in order to create an application that's beneficial to all who use it.

1301 Sansome Street, San Francisco, CA 94111