|
Acknowledgment:
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.
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:
- 200: The request has succeeded.
- 404: In case the server hasn't found anything matching the requested
file.
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.
|