Most Web applications use a request/response model to obtain a complete HTML page from the server. It is often a repetitive process of clicking a button, waiting for the server to respond, clicking another button, and then waiting again. With Ajax and the XMLHttpRequest object, you can use a request/response model that doesn't require the user to wait for a response from the server. In this article, Brett McLaughlin explains how to create XMLHttpRequest instances that can adapt to different browsers, establish and send requests, and respond to the server.
In the previous article in this series (see Resources for a link), we introduced Ajax applications and examined the basic concepts that drive Ajax applications. At the core of this are a lot of technologies you probably already know: JavaScript, HTML and XHTML, a bit of dynamic HTML, and the DOM (Document Object Model). This article will zoom in on one point and focus on specific Ajax details.
In this article, you will begin to get in touch with the most basic and fundamental objects and programming methods related to Ajax: the XMLHttpRequest object. This object is really just a common thread that spans all Ajax applications, and as you might expect, you need to thoroughly understand this object to realize your full programming potential. In fact, sometimes you will find that to use XMLHttpRequest correctly, you obviously cannot use XMLHttpRequest. What is going on?
Web 2.0 at a Glance
Before delving into the code, let's take a look at recent perspectives -- it's important to be very clear about the concept of Web 2.0. When you hear the term Web 2.0, you should first ask "What is Web 1.0?" Although it is rare to hear people mention Web 1.0, in fact it refers to the traditional Web with a completely different request and response model. For example, go to the Amazon.com website and click a button or enter a search term. A request is sent to the server, and the response is returned to the browser. The request is not just a list of books and titles, but another complete HTML page. Therefore, you may see flickering or jittering when the web browser redraws the page with the new HTML. In fact, the requests and responses are clearly visible with every new page you see.
Web 2.0 (largely) eliminates this visible back-and-forth interaction. For example, visit a site like Google Maps or Flickr (see Resources for links to these Web 2.0 and Ajax-enabled sites). On Google Maps, for example, you can drag the map to zoom in and out with minimal redrawing. Of course there are still requests and responses, but they are hidden behind the scenes. As a user, the experience is more comfortable and feels much like a desktop application. This new feeling and paradigm is what you get when someone mentions Web 2.0.
The concern is making these new interactions possible. Obviously, you still need to make requests and receive responses, but it's the HTML redrawing for each request/response interaction that creates the feeling of slow, clunky Web interactions. So it's clear that we need a way to send requests and receive responses that only contain the required data rather than the entire HTML page. The only time you need to get the entire new HTML page is when you want the user to see the new page.
But most interactions add details to existing pages, modify the main text, or overwrite original data. In these cases, Ajax and Web 2.0 methods allow data to be sent and received without updating the entire HTML page. For those who spend a lot of time online, this ability can make your applications feel faster and more responsive, keeping them coming back to your site from time to time.
Introduction to XMLHttpRequest
To truly realize this gorgeous miracle, you must be very familiar with a JavaScript object, namely XMLHttpRequest. This little object has actually been around in several browsers for a while, and is at the heart of Web 2.0, Ajax, and much of the other stuff I'll cover in this column over the next few months. To give you a quick overview, here are just a few of the methods and properties that will be used on this object.
·open(): Establish a new request to the server.
·send(): Send a request to the server.
·abort(): Abort the current request.
·readyState: Provides the ready state of the current HTML.
·responseText: The request response text returned by the server.
Don't worry if you don't know these (or any of them), we'll cover each method and property in the next few articles. What you should know now is exactly what to do with XMLHttpRequest. Note that these methods and properties are related to sending requests and processing responses. In fact, if you look at all the methods and properties of XMLHttpRequest, you'll find that they all relate to a very simple request/response model. Obviously, we're not going to encounter a particularly new GUI object or some super arcane way of creating user interaction, we're going to use very simple requests and very simple responses. It may not sound like much, but using this object well can revolutionize your application.
Simple new
first requires creating a new variable and assigning it an XMLHttpRequest object instance. This is as simple as using the new keyword on the object name in JavaScript, as shown in Listing 1.
Listing 1. Creating a new XMLHttpRequest object
<script language="javascript" type="text/javascript">
var request = new XMLHttpRequest();
</script>
Isn’t it difficult? Remember, JavaScript doesn't require you to specify variable types, so you don't need to do what you do in Listing 2 (which you might do in the Java language).
Listing 2. Java pseudocode for creating an XMLHttpRequestXMLHttpRequest
request = new XMLHttpRequest();
So in JavaScript you create a variable using var, give it a name (such as "request"), and then assign it a new XMLHttpRequest instance. The object can then be used in functions.
Error Handling
All kinds of things can actually go wrong, and the above code doesn't provide any error handling. A better approach is to create the object and exit gracefully if something goes wrong. For example, any older browsers (believe it or not, there are still people using older versions of Netscape Navigator) do not support XMLHttpRequest, and you need to let these users know that something is wrong. Listing 3 shows how to create this object to emit a JavaScript warning when a problem occurs.
Listing 3. Creating an XMLHttpRequest with error handling capabilities
<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (failed) {
request = false;
}
if (!request)
alert("Error initializing XMLHttpRequest!");
</script>
Be sure to understand these steps:
1. Create a new variable request and assign it a value of false. False will be used as the judgment condition later, which means that the XMLHttpRequest object has not been created yet.
2. Add try/catch block:
1) Try to create an XMLHttpRequest object.
2) If it fails (catch (failed)), it is guaranteed that the value of request is still false.
3. Check whether request is still false (it won't be false if everything is normal).
4. If a problem occurs (request is false), use JavaScript warning to notify the user that a problem has occurred.
The code is very simple, and for most JavaScript and web developers, it will take longer to truly understand it than to read and write the code. Now you have a piece of XMLHttpRequest object creation code that is error-checked and can tell you what went wrong.
Everything seems to be finewith Microsoft
, at least until you try out the code with Internet Explorer. If you experiment like this, you will see the bad situation shown in Figure 1.
Figure 1. Internet Explorer reporting error
Something is clearly wrong, and Internet Explorer is hardly an outdated browser since it is used by 70% of the world. In other words, if you don't support Microsoft and Internet Explorer, you won't be popular in the Web world! So we need to take a different approach with Microsoft browsers.
It was verified that Microsoft supports Ajax, but its XMLHttpRequest version has a different name. In fact, it calls it several different things. If you use newer versions of Internet Explorer, you need to use the object Msxml2.XMLHTTP, while older versions of Internet Explorer use Microsoft.XMLHTTP. We need to support both object types (as well as non-Microsoft browsers). Take a look at Listing 4, which builds on the preceding code and adds support for Microsoft.
Is Microsoft involved?
Much has been written about Ajax and Microsoft's growing interest and involvement in this area. In fact, it is said that Microsoft's latest version of Internet Explorer -- version 7.0, due out in the second half of 2006 -- will begin supporting XMLHttpRequest directly, letting you use the new keyword instead of all Msxml2.XMLHTTP creation code. But don't get too excited, older browsers still need to be supported, so cross-browser code isn't going away anytime soon.
Listing 4. Adding support for Microsoft browsers
<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
</script>
It is easy to be confused by these curly braces, so each step is introduced below:
1. Create a new variable request and assign it a value of false. Use false as the judgment condition, which means that the XMLHttpRequest object has not been created yet.
2. Add try/catch block:
1) Try to create an XMLHttpRequest object.
2) If it fails (catch (trymicrosoft)):
1>Try to use a newer version of Microsoft browser to create a Microsoft compatible object (Msxml2.XMLHTTP).
2> If failed (catch (othermicrosoft)) try to create a Microsoft compatible object (Microsoft.XMLHTTP) using an older version of Microsoft browser.
2) If it fails (catch (failed)), it is guaranteed that the value of request is still false.
3. Check whether request is still false (it won't be false if everything goes well).
4. If a problem occurs (request is false), use JavaScript warning to notify the user that a problem has occurred.
After modifying the code in this way and testing it using Internet Explorer, you should see the form that has been created (without an error message). The results of my experiment are shown in Figure 2.
Figure 2. Internet Explorer working normally
Static vs. dynamic
Take another look at Listings 1, 3, and 4. Notice that all of this code is nested directly within the script tag. JavaScript code like this that is not placed in a method or function body is called static JavaScript. This means that the code is run at some time before the page is displayed to the user. (Although the specification doesn't know with complete precision what effect this code will have on the browser when it is run, it is guaranteed that it will be run before the user can interact with the page.) This is also the general way most Ajax programmers create XMLHttpRequest objects.
That said, you could also put this code in a method like Listing 5.
Listing 5. Moving XMLHttpRequest creation code into a method
<script language="javascript" type="text/javascript">
var request;
function createRequest() {
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
}
</script>
If you write your code this way, you need to call this method before handling Ajax. So code like Listing 6 is also needed.
Listing 6. Create method using XMLHttpRequest
<script language="javascript" type="text/javascript">
var request;
function createRequest() {
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
}
function getCustomerInfo() {
createRequest();
// Do something with the request variable
}
</script>
The only problem with this code is that it delays error notification, which is why most Ajax programmers don't use this approach. Suppose you have a complex form with 10 or 15 fields, select boxes, etc., and you want to activate some Ajax code when the user enters text in the 14th field (from top to bottom in the order of the form). At this point running getCustomerInfo() attempts to create an XMLHttpRequest object, but (in this case) fails. The user is then shown a warning clearly telling them they cannot use the app. But users already spend a lot of time entering data into forms! This is very annoying, and being annoying will obviously not attract users to come back to your site.
If you use static JavaScript, users will see error messages very quickly when they click on the page. That's annoying too, isn't it? The user may mistakenly believe that your Web application cannot run on his browser. But it's certainly better than them spending 10 minutes entering information only to be shown the same error later. Therefore, I recommend writing static code to allow users to detect problems as early as possible.
Aftersending a request with XMLHttpRequest
and getting the request object, you can enter the request/response cycle. Remember, the only purpose of XMLHttpRequest is to let you send requests and receive responses. Everything else is the job of JavaScript, CSS, or other code in the page: changing the user interface, switching images, interpreting data returned by the server. After preparing the XMLHttpRequest, you can send the request to the server.
Welcome to Sandbox
Ajax uses a sandbox security model. Therefore, Ajax code (specifically, the XMLHttpRequest object) can only send requests to the same domain in which it is located. We'll cover more about security and Ajax in a future article, but for now just know that code running on the local machine can only make requests to server-side scripts on the local machine. If you want the Ajax code to run on www.breakneckpizza.com , the request must be sent from a script running in www.breakneck.com .
To set the server URL,
you must first determine the URL of the connected server. This is not a special requirement for Ajax, but it is still necessary to establish the connection, and now you should obviously know how to construct a URL. In most applications, this URL is constructed from a combination of some static data and data from a form that the user processes. For example, the JavaScript code in Listing 7 gets the value of the phone number field and uses it to construct a URL.
Listing 7. Creating the request URL
<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
}
</script>
Nothing difficult to understand here. First, the code creates a new variable phone and assigns it the value of the form field with the ID "phone". Listing 8 shows the XHTML for this form, where you can see the phone field and its id attribute.
Listing 8. Break Neck Pizza form
<body>
<p><img src="breakneck-logo_4c.gif" alt="Break Neck Pizza" /></p>
<form action="POST">
<p>Enter your phone number:
<input type="text" size="14" name="phone" id="phone"
onChange="getCustomerInfo();" />
</p>
<p>Your order will be delivered</p>
<div id="address"></div>
<p>Type your order in here:</p>
<p><textarea name="order" rows="6" cols="50" id="order"></textarea></p>
<p><input type="submit" value="Order Pizza" id="submit" /></p>
</form>
</body>
Also note that when the user enters a phone number or changes the phone number, the getCustomerInfo() method shown in Listing 8 is triggered. This method gets the phone number and constructs a URL string stored in the url variable. Remember, because the Ajax code is sandboxed and can only connect to the same domain, there is actually no need for a domain name in the URL. The script in this example is called /cgi-local/lookupCustomer.php. Finally, the phone number is appended to the script as a GET parameter: "phone=" + escape(phone).
If you haven't seen the escape() method before, it is used to escape any characters that cannot be sent correctly in clear text. For example, spaces in phone numbers will be converted to the characters %20, allowing these characters to be passed in the URL.
You can add as many parameters as needed. For example, if you need to add another parameter, just append it to the URL and separate it with the ampersand (&) character [the first parameter is separated from the script name with a question mark (?)].
Open the request
Once you have the URL to connect to, you can configure the request. This can be accomplished using the open() method of the XMLHttpRequest object. This method has five parameters:
request-type: the type of request to send. Typical values are GET or POST, but a HEAD request can also be sent.
url: The URL to connect to.
asynch: true if you want to use an asynchronous connection, false otherwise. This parameter is optional and defaults to true.
username: If authentication is required, you can specify the username here. This optional parameter has no default value. password: If authentication is required, you can specify a password here. This optional parameter has no default value.
Does open() open?
Internet developers don't agree on what exactly the open() method does. But it doesn't actually open a request. If you monitor the network and data transfer between an XHTML/Ajax page and its connecting script, you will not see any communication when the open() method is called. It's unclear why this name was chosen, but it's clearly not a good choice.
Usually the first three parameters are used. In fact, even if an asynchronous connection is required, the third parameter should be specified as "true". This is the default, but insisting on explicitly specifying whether the request is asynchronous or synchronous is easier to understand.
Combining these together usually results in a line of code like the one shown in Listing 9.
Listing 9. Open request
function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
}
Once you set up the URL, the rest is easy. For most requests, GET is enough (you'll see when POST is required in a later article), plus the URL, and that's all you need to use the open() method.
Challenging Asynchronicity
In the next article in this series, I'll spend a lot of time writing and using asynchronous code, but you should understand why the last parameter of open() is so important. In a general request/response model, such as Web 1.0, the client (a browser or code running on the local machine) makes a request to the server. The request is synchronous, in other words, the client waits for a response from the server. When the client is waiting, you will be notified of the wait in at least some form:
·Hourglass (especially on Windows).
·Spinning ball (usually on Mac machines).
·The application basically freezes and then after a while the cursor changes.
This is exactly why Web applications feel clunky or slow—a lack of true interactivity. When the button is pressed, the application effectively becomes unusable until the request that was just triggered is responded to. If the request requires a lot of server processing, the wait time can be long (at least in this multiprocessor, DSL-no-wait world).
Asynchronous requests do not wait for a response from the server. The application continues running after sending the request. Users can still enter data in the Web form or even navigate away from the form. There are no spinning balls or hourglasses, and the app doesn't freeze noticeably. The server quietly responds to the request, and when it's done, tells the original requester that the job is finished (you'll see how soon). The result is an app that feels less laggy or sluggish and more responsive, interactive, and feels much faster. This is just one part of Web 2.0, but it's an important part. All the old GUI components and Web design paradigms can't overcome the slow, synchronous request/response model.
Sending Requests
Once configured with open(), you can send requests. Fortunately, the method for sending requests has a more appropriate name than open(): it is send().
send() has only one parameter, which is the content to be sent. But before considering this method, recall that you have already sent data through the URL itself:
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
Although you can use send() to send data, But it is also possible to send data via the URL itself. In fact, with GET requests (which occur in about 80% of typical Ajax applications), it's much easier to send data using a URL. If you need to send secure information or XML, you might want to consider using send() to send the content (secure data and XML messages will be discussed in subsequent articles in this series). If you do not need to pass data through send(), just pass null as the parameter of this method. So you'll find that this is all you need to do in the examples in this article (see Listing 10).
Listing 10. Send request
function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.send(null);
}
Specify the callback method
There is very little about what we do now that is new, revolutionary, or asynchronous. It must be admitted that the little keyword "true" in the open() method establishes an asynchronous request. But other than that, the code is no different than programming with Java servlets and JSP, PHP, or Perl. So what's the biggest secret of Ajax and Web 2.0? The secret lies in a simple property onreadystatechange of XMLHttpRequest.
Be sure to understand the flow in this code first (review Listing 10 if necessary). Build its request and then make the request. Additionally, because the request is asynchronous, the JavaScript method (getCustomerInfo() in the example) does not wait for the server. So the code will continue to execute, that is, the method will exit and control will be returned to the form. The user can continue to enter information and the application does not wait for the server.
This raises an interesting question: What happens after the server completes the request? The answer is that nothing happens, at least for the current code! Obviously this won't work, so the server needs some kind of instructions on what to do after it's finished processing the request sent to it via XMLHttpRequest.
Reference functions in JavaScript:
JavaScript is a weakly typed language and you can use variables to reference anything. So if you declare a function updatePage(), JavaScript also treats the function name as a variable. In other words, you can reference the function in your code using the variable name updatePage.
Listing 11. Set callback method
function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
It's important to note where in the code this property is set - it is set before send() is called. This property must be set before sending the request so that the server can view it after answering the completed request. Now all that's left is to write the updatePage() method, which is the focus of the last section of this article.
The processing server responds
to the request, the user is happily using the Web form (while the server is processing the request), and now the server has completed processing the request. The server looks at the onreadystatechange attribute to determine which method to call. Otherwise, treat your application like any other application, whether asynchronous or not. In other words, you don't necessarily have to take special action to write a method that responds to the server, you just need to change the form, let the user visit another URL or do whatever the response server needs. In this section we focus on responses to the server and a typical action - instantly changing part of the form that the user sees.
Callbacks and Ajax
Now we've seen how to tell the server what to do when it's done: set the XMLHttpRequest object's onreadystatechange property to the name of the function to be run. In this way, the function will be called automatically after the server has processed the request. There is also no need to worry about any parameters of the function. We start with a simple method, shown in Listing 12.
Listing 12. Code for the callback method
<script language="javascript" type="text/javascript">
var request = false;
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (othermicrosoft) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = false;
}
}
}
if (!request)
alert("Error initializing XMLHttpRequest!");
function getCustomerInfo() {
var phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
}
function updatePage() {
alert("Server is done!");
}
</script>
It just issues some simple warnings to tell you when the server has completed its task. Try this code out on your own web page and open it in a browser (see Listing 8 if you want to see the XHTML in this example). Enter the phone number and then leave the field, you will see a pop-up warning window (as shown in Figure 3), but click OK and it will appear again...
Figure 3. Ajax code for the pop-up warning
Depending on the browser, you may see two, three, or even four warnings before the form stops popping up. What's going on? It turns out we haven't considered the HTTP readiness state, which is an important part of the request/response cycle.
HTTP Ready State
As mentioned earlier, the server looks for the method to be called in the onreadystatechange attribute of XMLHttpRequest after completing the request. This is true, but incomplete. In fact, it calls this method every time the HTTP ready status changes. What does this mean? First you must understand the HTTP readiness state.
The HTTP ready status represents the status or condition of the request. It is used to determine whether the request has been started, received a response, or the request/response model has been completed. It can also help determine whether it is safe to read the response text or data provided by the server. There are five readiness states to be aware of in Ajax applications:
·0: The request has not been issued (before open() is called).
·1: The request has been established but not yet sent (before send() is called).
·2: The request has been sent and is being processed (the content header can usually be obtained from the response).
·3: The request has been processed and some data is usually available in the response, but the server has not completed the response.
·4: The response is complete and you can access the server response and use it.
As with most cross-browser issues, these ready states are not used consistently. You might expect the task readiness status to go from 0 to 1, to 2, to 3, to 4, but this is rarely the case. Some browsers never report 0 or 1 but start directly with 2, then 3 and 4. Other browsers report all statuses. Others report ready status 1 multiple times. As seen in the previous section, the server calls updatePage() multiple times, and a warning box pops up every time it is called - it may be different from what is expected!
For Ajax programming, the only state that needs to be handled directly is ready state 4, which indicates that the server response is complete and the response data is safe to use. Based on this, the first line in the callback method should look like Listing 13.
Listing 13. Checking readiness
function updatePage() {
if (request. readyState == 4)
alert("Server is done!");
}
After modification, you can ensure that the server's processing has been completed. Try running the new version of the Ajax code and you will now see the warning message displayed only once, as expected.
HTTP Status Codes
Although the code in Listing 13 seems fine, there's a problem - what if the server responds to the request and completes the processing but reports an error? Be aware that server-side code should understand that it is being called by Ajax, JSP, plain HTML forms, or other types of code, but can only report information using traditional Web-specific methods. In the Web world, HTTP code can handle various problems that may occur in the request.
For example, you must have encountered the situation where you entered the wrong URL request and got a 404 error code, which means that the page does not exist. This is just one of many error codes that can be received with an HTTP request (see the link in Resources for a complete list of status codes). 403 and 401, which indicate that the data being accessed is protected or prohibited, are also common. In either case, these error codes are obtained from the completed response. In other words, the server fulfilled the request (that is, the HTTP ready status is 4) but did not return the data that the client expected.
So in addition to the ready status, you also need to check the HTTP status. The expected status code is 200, which means everything went well. If the ready status is 4 and the status code is 200, you can process the server's data, and the data should be the requested data (rather than errors or other problematic information). Therefore, we also need to add a status check in the callback method, as shown in Listing 14.
Listing 14. Check HTTP status code
function updatePage() {
if (request. readyState == 4)
if (request.status == 200)
alert("Server is done!");
}
To add more robust error handling and try to avoid over-complication by adding a status code check or two, take a look at the modified version of updatePage() in Listing 15.
Listing 15. Add a little error checking
function updatePage() {
if (request. readyState == 4)
if (request.status == 200)
alert("Server is done!");
else if (request.status == 404)
alert("Request URL does not exist");
else
alert("Error: status code is " + request.status);
}
Now change the URL in getCustomerInfo() to a non-existent URL and see what happens. You should see a warning message stating that the requested URL does not exist - great! It's difficult to handle all error conditions, but this small change can cover 80% of the problems in a typical Web application.
Reading the response text
now ensures that the request has been processed (via the ready status), the server gave a normal response (via the status code), and finally we can process the data returned by the server. The returned data is stored in the responseText property of the XMLHttpRequest object.
The content of the text in responseText, such as format and length, is intentionally left vague. This way the server can set the text to anything. For example, one script might return comma-separated values, another uses a pipe (the | character) to separate values, and yet another returns a long text string. It's up to the server to decide where to go.
In the example used in this article, the server returns the customer's last order and customer address, separated by a pipe character. The order and address are then used to set element values in the form. Listing 16 shows the code to update the display.
Listing 16. Handling server response
function updatePage() {
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText.split("|");
document.getElementById("order").value = response[0];
document.getElementById("address").innerHTML =
response[1].replace(/n/g, "");
} else
alert("status is " + request.status);
}
}
First, get the responseText and split it from the pipe using JavaScript split() method. The resulting array is placed in response. The first value in the array - the previous order - is accessed with response[0] and is set to the value of the field with ID "order". The second value response[1], the customer address, requires a little more processing. Because the lines in the address are separated by normal line separators ("n" characters), the code needs to use XHTML-style line separators<br /> instead. The replacement process is done using the replace() function and regular expressions. Finally, the modified text is used as inner HTML in the HTML form div. The result is that the form suddenly updates with the customer information, as shown in Figure 4.
Figure 4. Break Neck form after receiving customer data
Before ending this article, I would like to introduce another important attribute of XMLHttpRequest, responseXML. This property contains (as you may have guessed) the XML response if the server chooses to use an XML response. Processing XML responses is very different from processing ordinary text, involving parsing, the Document Object Model (DOM), and other issues. XML will be covered further in a later article. But since responseXML is usually discussed together with responseText, it deserves a mention here. For many simple Ajax applications responseText will suffice, but you'll soon see that XML can also be handled well with Ajax applications.
Conclusion
You may be a little tired of XMLHttpRequest. I rarely see an entire article discussing an object, especially such a simple object. But you'll use this object again and again in every page and application you write using Ajax. Frankly speaking, there are really some content about XMLHTTPREQUEST. In the next article, you will introduce how to use posts and get in the request to set the content head of the request and read the content head from the server to respond to the content of the content, and understand how to encode the request and process XML in the request/response model.
After that, we will introduce a common AJAX toolbox. These toolboxes actually hide many details described herein, making AJAX programming easier. You may think that since there are so many toolboxes, why do you need to encode the underlying details. The answer is that if you don't know what the application is doing, it is difficult to find the problem in the application.
So don't ignore these details or browse it simply. If there is an error in the convenient and gorgeous toolbox, you don't have to scratch your head or send an email request for support. If you know how to use XMLHTTPREQUEST directly, you will find that it is easy to debug and solve the strangest problem. Only by letting it solve your problem, the toolbox is a good thing.
So be familiar with XMLHTTPREQUEST. In fact, if you have the AJAX code of the toolbox, you can try to rewrite the Xmlhttprequest object and its attributes and methods. This is a good practice that can help you better understand the principle.
In the next article, we will further discuss this object to explore some more interesting attributes (such as Responsexml), and how to use post requests and send data in different formats. Please start writing the code, we will continue to discuss one month later.