Understanding Ajax: Page 4
[previous]
Understanding Ajax: Getting Started
2.3 Sending Asynchronous Requests
Synchronous requests are easier to use than asynchronous requests because they return data directly and remove the hassle of creating callback functions. However, they aren’t the standard use case for XMLHttpRequest
because the entire browser is locked while the request is happening. There are some circumstances in which blocking is useful (mainly when a decision needs to be made before the current function ends), but in most cases, you’ll want these requests to happen in the background. An asynchronous request allows the browser to continue running JavaScript code and users to continue interacting with the page while the new data is loaded. With the proper user interface, asynchronous communication allows an Ajax application to be useful even when the user’s connection to the site is slow.
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:
-
requestType
(line 4). Used to set the HTTP request type,GET
is used to request content that doesn’t perform an action whereasPOST
is used for requests that do. -
isAsync
(line 6). A Boolean value used to set the request method. The default is false, which makes an synchronous request. If you’re making an asynchronous request,isAsync
is set totrue
. When making an asynchronous request, you also need to set thecallback
property. -
callback
(line 12). This property takes a function that takes a single parameter result and is called when a request is successfully completed.
Lines 16–31 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 16–19). When it completes, it is hidden again (lines 23–26). The class also defines a function to call when an error happens (lines 29–31); 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 33–56 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 62–79) 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 82–99) 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 12–17); the test
function first sets up a callback to run when the request is complete (lines 13–15), and then it calls makeRequest
(line 16), which starts the Ajax call.
2.4 Ajax Without XMLHttpRequest
There are a number of cases in which you might not have XMLHttpRequest
support. The most common would be in the case of an older browser. This is the hardest to work around, not because there is no Ajax fallback, but because all the other DOM manipulation that you do within the application won’t work. Another problem case is when your browser supports everything that is needed except for XMLHttpRequest
. This problem could occur when IE is in a mode where it can’t use ActiveXObjects
or when you are using a pre-7.6 version of Opera. In some cases, especially intranet applications, it’s easy to just require an upgrade, but if you want to use Ajax on a public site, you’ll want to think about using some sort of fallback mechanism. The best candidate for a fallback is to use hidden IFrames
. Another option is to use cookies, but they can send only a limited amount of data per request, so it is hard to drop in cookie-based approaches as a replacement for code that has been written with XMLHttpRequest
in mind. Only XMLHttpRequest
supports synchronous calls, so if they are necessary for your application, then using it as a fallback will not be possible.
If you’re using a fully wrapped XMLHttpRequest
and you don’t use synchronous calls, providing transparent fallback to your program should be possible. You need only to replace the final throwing of an exception in the example init
method with the instantiation of your IFrame
HTTP client. The main item to remember about using another approach instead of XMLHttpRequest
is that it’s not going to gain you huge leaps in compatibility. The major browsers already support XMLHttpRequest
. This support makes browsers with JavaScript turned off, not those running an unsupported browser, the biggest group that can’t use your Ajax application. The advantages and disadvantages of the Ajax communication techniques are shown in Table 2-2.
Table 2-2 Advantages and Disadvantages of Ajax Techniques
Technique |
Advantages |
Disadvantages |
|
Can make requests to pages not set up for Ajax Can set/get all HTTP headers
Can make HTTP requests using any type (
Supports full control over Requests ActiveX to be enabled in IE 5 and 6 |
Is only available in newer versions of Opera and Safari Has small implementation differences between browsers |
|
Can make Supportes all modern browsers Supports asynchronous file uploads |
Prohibits synchronous requests
Server pages must be designed to work with Has implementation differences between browsers Can leave extra entries in browser history (depends on browser and implementation) All request data is URL-encoded, increasing request size |
Cookies |
Supports the largest number of browsers Few implementation differences between browsers Prohibits no synchronous requests |
Doesn’t work with large requests/results Requires server pages to be designed to work with cookie requests Requires polling on the client
Can make only |
This excerpt is taken from Chapter 2 of Understanding Ajax: Using JavaScript to Create Rich Internet Applications, written by Joshua Eichorn, and published by Pearson Education, Inc., Copyright © 2007 Pearson Education, Inc. All rights reserved.
[previous]
URL: