The XML HTTP Request Object
The XML HTTP Request Object
Advanced Search
ADC Home > Internet & Web > Web Content >
As deployment of XML data and web services becomes more widespread, you may occasionally find it
convenient to connect an HTML presentation directly to XML data for interim updates without reloading the
page. Thanks to the littleknown XMLHttpRequest object, an increasing range of web clients can retrieve and
submit XML data directly, all in the background. To convert retrieved XML data into renderable HTML content,
rely on the clientside Document Object Model (DOM) to read the XML document node tree and compose HTML
elements that the user sees.
History and Support
Microsoft first implemented the XMLHttpRequest object in Internet Explorer 5 for Windows as an ActiveX
object. Engineers on the Mozilla project implemented a compatible native version for Mozilla 1.0 (and Netscape
7). Apple has done the same starting with Safari 1.2.
Similar functionality is covered in a proposed W3C standard, Document Object Model (DOM) Level 3 Load and
Save Specification. In the meantime, growing support for the XMLHttpRequest object means that is has
become a de facto standard that will likely be supported even after the W3C specification becomes final and
starts being implemented in released browsers (whenever that might be).
Creating the Object
Creating an instance of the XMLHttpRequest object requires branching syntax to account for browser
differences in the way instances of the object are generated. For Safari and Mozilla, a simple call to the object's
constructor function does the job:
var req = new XMLHttpRequest();
For the ActiveX branch, pass the name of the object to the ActiveX constructor:
var req = new ActiveXObject("Microsoft.XMLHTTP");
The object reference returned by both constructors is to an abstract object that works entirely out of view of
the user. Its methods control all operations, while its properties hold, among other things, various data pieces
returned from the server.
Object Methods
Instances of the XMLHttpRequest object in all supported environments share a concise, but powerful, list of
methods and properties. Table 1 shows the methods supported by Safari 1.2, Mozilla, and Windows IE 5 or
later.
Table 1. Common XMLHttpRequest Object Methods
Method Description
abort() Stops the current request
getAllResponseHeaders() Returns complete set of headers (labels and values)
as a string
getResponseHeader("headerLabel") Returns the string value of a single header label
open("method", "URL"[, asyncFlag[, Assigns destination URL, method, and other optional
"userName"[, "password"]]]) attributes of a pending request
send(content) Transmits the request, optionally with postable
string or DOM object data
setRequestHeader("label", "value") Assigns a label/value pair to the header to be sent
with a request
Of the methods shown in Table 1, the open() and send() methods are the ones you'll likely use most. The
first, open() , sets the scene for an upcoming operation. Two required parameters are the HTTP method you
intend for the request and the URL for the connection. For the method parameter, use "GET" on operations that
are primarily data retrieval requests; use "POST" on operations that send data to the server, especially if the
length of the outgoing data is potentially greater than 512 bytes. The URL may be either a complete or relative
URL (but see security issues below).
An important optional third parameter is a Boolean value that controls whether the upcoming transaction
should be handled asynchronously. The default behavior ( true) is to act asynchronously, which means that
script processing carries on immediately after the send() method is invoked, without waiting for a response. If
you set this value to false, however, the script waits for the request to be sent and for a response to arrive
from the server. While it might seem like a good idea to wait for a response before continuing processing, you
run the risk of having your script hang if a network or server problem prevents completion of the transaction. It
is safer to send asynchronously and design your code around the onreadystatechange event for the request
object.
The following generic function includes branched object creation, event handler assignment, and submission of
a GET request. A single function argument is a string containing the desired URL. The function assumes that a
global variable, req, receives the value returned from the object constructors. Using a global variable here
allows the response values to be accessed freely inside other functions elsewhere on the page. Also assumed in
this example is the existence of a processReqChange() function that will handle changes to the state of the
request object.
var req;
function loadXMLDoc(url) {
req = false;
// branch for native XMLHttpRequest object
if(window.XMLHttpRequest) {
try {
req = new XMLHttpRequest();
} catch(e) {
req = false;
}
// branch for IE/Windows ActiveX version
} else if(window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
req = false;
}
}
}
if(req) {
req.onreadystatechange = processReqChange;
req.open("GET", url, true);
req.send("");
}
}
Note: It is essential that the data returned from the server be sent with a ContentType set to text/xml .
Content that is sent as text/plain or text/html is accepted by the instance of the request object however it
will only be available for use via the responseText property.
Object Properties
Once a request has been sent, scripts can look to several properties that all implementations have in common,
shown in Table 2. All properties are readonly.
Table 2. Common XMLHttpRequest Object Properties
Property Description
onreadystatechange Event handler for an event that fires at every state change
readyState Object status integer:
0 = uninitialized
1 = loading
2 = loaded
3 = interactive
4 = complete
responseText String version of data returned from server process
responseXML DOMcompatible document object of data returned from server process
status Numeric code returned by server, such as 404 for "Not Found" or 200 for "OK"
statusText String message accompanying the status code
Use the readyState property inside the event handler function that processes request object state change
events. While the object may undergo interim state changes during its creation and processing, the value that
signals the completion of the transaction is 4.
You still need more confirmation that the transaction completed successfully before daring to operate on the
results. Read the status or statusText properties to determine the success or failure of the operation.
Respective property values of 200 and OK indicate success.
The following listing shows a skeletal onreadystatechange event handler function that allows processing of the
response content only if all conditions are right.
function processReqChange() {
// only if req shows "loaded"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
// ...processing statements go here...
} else {
alert("There was a problem retrieving the XML data:\n" +
req.statusText);
}
}
}
If you are concerned about possible timeouts of your server process, you can modify the loadXMLDoc()
function to save a global timestamp of the send() method, and then modify the event handler function to
calculate the elapsed time with each firing of the event. If the time exceeds an acceptable limit, then invoke the
req.abort() method to cancel the send operation, and alert the user about the failure.
Security Issues
When the XMLHttpRequest object operates within a browser, it adopts the samedomain security policies of
typical JavaScript activity (sharing the same "sandbox," as it were). This has some important implications that
will impact your application of this feature.
First, on most browsers supporting this functionality, the page that bears scripts accessing the object needs to
be retrieved via http: protocol, meaning that you won't be able to test the pages from a local hard disk ( file:
protocol) without some extra security issues cropping up, especially in Mozilla and IE on Windows. In fact,
Mozilla requires that you wrap access to the object inside UniversalBrowserRead security privileges. IE, on the
other hand, simply displays an alert to the user that a potentially unsafe activity may be going on and offers a
chance to cancel.
Second, the domain of the URL request destination must be the same as the one that serves up the page
containing the script. This means, unfortunately, that clientside scripts cannot fetch web service data from
other sources, and blend that data into a page. Everything must come from the same domain. Under these
circumstances, you don't have to worry about security alerts frightening your users.
An Example: Reading XML Data from iTunes RSS Feeds
You can play with an example that points to four static XML files for demonstration purposes. The data sources
are snapshots of some iTunes Storerelated RSS feeds. Because the actual feeds are hosted at a thirdparty
domain, the mixed domains of the example file and live RSS sources prevents a truly dynamic example.
When you choose one of the four listing categories, the script loads the associated XML file for that category.
Further scripts extract various element data from the XML file to modify the options in a second select
element. A click on one of the items reads a different element within that item's XML data. That data happens
to be HTML content, which is displayed within the example page without reloading the page.
Note that the sample data includes some elements whose tag names contain namespace designations. Internet
Explorer for Windows (at least through Version 6) does not implement the DOM getElementsByTagNameNS()
function. Instead it treats namespace tag names literally. For example, the <content:encoded> element is
treated as an element whose tag name is content:encoded, rather than a tag whose local name is encoded and
whose prefix is content. The example includes a utility API function called getElementTextNS() which handles
the object model disparities, while also retrieving the text node contained by the desired element.
If you download the examples (DMG 2.0MB), you can test it yourself by placing it in your personal web server's
Sites folder, and accessing the page via the http: protocol. Keep all files, including the XML samples, in the
same directory.
A Cool Combo
For years, advanced clientside developers have frequently wanted a clean way to maintain a "connection" with
the server so that transactions can occur in the background, and newly updated data gets inserted into the
current page. Many have tortured themselves by using techniques such as hidden selfrefreshing frames and
"faceless" Java applets. In lieu of a W3C standard still under development, the Microsoftborn XMLHttpRequest
object fills an important gap that should inspire application development creativity. The feature is a welcome
addition to Safari.
Updated: 20050624
Get information on Apple products.
Visit the Apple Store online or at retail locations.
1800MYAPPLE
Copyright © 2005 Apple Computer, Inc.
All rights reserved. | Terms of use | Privacy Notice