|
|
|
Introducing XMLHttpRequest object
|
|
XMLHttpRequest: The term is becoming more and more familiar these days, especially in conjunction with AJAX. You might find it interesting to note that this XMLHttpRequest object is not something new. Microsoft first implemented the XMLHttpRequest object in Internet Explorer 5 for Windows as an ActiveX object. It is a powerful concept but till AJAX arrived there were very few people who knew about this and fewer who tried to do something with this. Also interesting to note is that a similar functionality is covered in a proposed W3C standard, Document Object Model (DOM) Level 3 Load and Save Specification. Going with the way things are now it appears that XMLHttpRequest is fast becoming a de-facto industry standard.
|
|
What can I do with this XMLHttpRequest object?
|
|
An increasing range of web clients can retrieve and submit XML data directly, all in the background. The data retrieved via this can then be rendered as HTML content, after desired processing using client-side Document Object Model (DOM).
|
|
How do I put this in use?
|
|
Ok enough of introduction let us get down to some basics here.
|
|
Creating the Object: Creating an instance of the XMLHttpRequest object will require different statements for different browsers as XMLHttpRequest object is implemented differently by various browsers.
|
|
For Safari and Mozilla: var req = new XMLHttpRequest();
|
|
For Microsoft IE: 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: Fortunately even though creation of XMLHttpObject differs across browsers yet all of them support some common methods which are described below.
|
| 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[, "userName"[, "password"]]]) | Assigns destination URL, method, and other optional 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 above, the open() and send() methods need special mention as these are the ones you are likely to often most of the times.
|
|
open() establishes the connection with URL passed as the parameter. For '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.
|
|
Object Properties: Here again we have a common set of properties honored by all browser implementations.
|
| Property | Description |
| Onreadystatechange | Event handler for an event that fires at every state change |
| readyState |
returns object status integer:
| 0 = uninitialized |
| 1 = loading |
| 2 = loaded |
| 3 = interactive |
| 4 = complete |
|
| responseText | String version of data returned from server process |
| responseXML | DOM-compatible 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.
|
|
Even though readyState property signals transaction complete you will be better off reading the status (value of '200' for success) or statusText (value of 'OK' for success) properties to determine the success or failure of the operation.
|
|
responseText provides the data returned from the server in string represenatation.
|
|
responseXML provides the more powerful XML document object as returned from the server. This object is a full-fledged document node object (a DOM nodeType of 9), which can be examined and parsed using W3C Document Object Model (DOM) node tree methods and properties.
|
|
Note: responseXML gives you an XML not HTML document, meaning that you cannot count on the DOM's HTML module methods and properties. This is not really a restriction because the Core DOM module gives you ample ways of finding element nodes, element attribute values, and text nodes nested inside elements.
|
|
Show me some code!
|
|
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, xmlhttp, 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 xmlhttpChange() function that will handle changes to the state of the request object.
|
var xmlhttp;
function loadXMLDoc() { // code for Mozilla, etc.
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest()
xmlhttp.onreadystatechange=xmlhttpChange;
xmlhttp.open("GET",url,true)
xmlhttp.send(null)
}
else if (window.ActiveXObject) { // code for IE
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP")
xmlhttp.onreadystatechange=xmlhttpChange;
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
}
|
|
Note: It is essential that the data returned from the server be sent with a Content-Type 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.
|
|
The following listing shows a skeletal onreadystatechange event handler function that allows processing of the response content only if all conditions are right.
|
function xmlhttpChange() {
//if xmlhttp shows "loaded"
if (xmlhttp.readyState==4) {
//if "OK"
if (xmlhttp.status==200) {
//get data as XML
var xmlDoc = xmlhttp.responseXML;
//get data as text
var textData = xmlhttp.responseText;
}
else {
alert("Problem retrieving data")
}
}
}
|
|
Note: If you are concerned about possible timeouts of your server process, you can modify the loadXMLDoc() function to save a global time-stamp 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.
|