The XMLHttpRequest Object
The XMLHttpRequest object is a built-into-the-browser (in IE and other recent browsers) JavaScript or ActiveX object that enables JavaScript to make HTTP requests to a remote server and receive HTTP responses from a remote server without the need to reload the page. There are two distinct implementations, depending upon the browser. Internet Explorer uses an ActiveX object, while non-IE browsers use a native JavaScript object. Despite its name, the XMLHttpRequest object is not limited to sending or retrieving XML, it can request or send any type of content.
The framework for this article uses a JavaScript function called
getHTTPObject to create the XMLHttpRequest object. The
getHTTPObject function has two separate code blocks to meet the needs of both IE and non-IE browsers as shown below:
function getHTTPObject()
{
var xmlhttp = null;
var success = false;
// List of MS XMLHTTP versions - newest first
var MSXML_XMLHTTP_PROGIDS = new Array(
'MSXML2.XMLHTTP.5.0',
'MSXML2.XMLHTTP.4.0',
'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP',
'Microsoft.XMLHTTP'
);
// test for IE implementations first
for (var i = 0; i < MSXML_XMLHTTP_PROGIDS.length &&
!success; i++)
{
try
{
xmlhttp = new ActiveXObject(
MSXML_XMLHTTP_PROGIDS[i]);
success = true;
return xmlhttp:
}
catch (e)
{
xmlhttp = false;
}
}
// Now test for non-IE implementations
if (!xmlhttp &&
typeof XMLHttpRequest != 'undefined')
{
try
{
xmlhttp = new XMLHttpRequest();
}
catch (e)
{
xmlhttp = false;
}
}
return xmlhttp:
}
Notice how the
getHTTPObject function first tests for IE implementations of the XMLHttpRequest object and then tests for non-IE implementations. You can use both implementations in a similar fashionin other words, once you have a reference to an XMLHttpRequest object, the method calls and properties are functionally similar, regardless of the underlying implementation.
After creating an XMLHttpRequest object, you simply set a few properties on it and invoke the
open and
send methods on it to send data to the server. The
callService JavaScript function illustrated previously demonstrates the send process.
When you make an asynchronous call to the XMLHttpRequest object, it repeatedly executes the callback function
handleServiceResponse (previously stored in the XMLHttpRequest object's
onreadystatechange property) until the server response is complete.
The
handleServiceResponse function queries the
readyState property of the XMLHttpRequest object to determine the completion state of the response. The
readyState property can have one the following possible values:
- 0 (UNINITIALIZED): open() has not been called yet.
- 1 (LOADING): send() has not been called yet.
- 2 (LOADED): send() has been called, headers and status are available.
- 3 (INTERACTIVE): Data is downloading.
- 4 (COMPLETED): Finished with all operations.
When the
readyState property indicates that the response has completed, you can retrieve the response data from the XMLHttpRequest object using either the
responseText or the
responseXML property. The
responseText property returns a string representation of the data and the
responseXML property returns an XML document object that you can then traverse as desired. The following code shows the
handleServiceResponse JavaScript function:
 | |
| Figure 3. The Populated User Form. After completing the background XMLHttpRequest call, the application displays both the raw XML data received and the extracted list of user names. |
Figure 3 shows the populated user form after a receiving a response from the server.
function handleServiceResponse()
{
if (httpObj.readyState == 4) // completed
{
isWorking = false;
if (httpObj.status == 200) // server "OK" response code
{
// the responseXML property retrieves an XML Document
var xmlDoc =
httpObj.responseXML.documentElement;
// the responseText property retrieves a string
document.ServiceRequestForm.result.value =
httpObj.responseText;
document.ServiceRequestForm.users.value = "";
// display the user list from the XML Document
var users = xmlDoc.getElementsByTagName("User");
for (var i = 0; i < users.length; i++)
{
if (i > 0)
{
document.ServiceRequestForm.users.value +=
"\n";
}
document.ServiceRequestForm.users.value +=
users.item(i).firstChild.data;
}
}
}
}
The preceding function retrieves the HTTP response as an XML document and then traverses that document to find the desired nodes. It then uses the data from these nodes to populate fields in the HTML form.