JavaScript XmlHttpRequest Library

A few days ago I have created a small library providing access to the XMLHttpRequest object, but in a more object oriented way than the original implementation does.

Core of this library is the XmlHttpRequest class (notice the capitalization). Using this class you can easily prepare and execute Ajax requests.

How to use this library

First, link to the XmlHttpRequest library file.

Next, create an XmlHttpRequest object from the library. Please note that all objects in this library reside in the "AxelDahmen" namespace. To create an XmlHttpRequest object you use the following code:

var xml = new AxelDahmen.XmlHttpRequest();

The easiest way to use this class is by sending a synchronous request to the web server. You just call the send() method of the XmlHttpRequest class:

var response = xml.send("http://www.contoso.com/sample.cgi", xml.type.GET);

The send() method requires two arguments:

If a synchronouos request doesn't meet your needs, you can as easily initiate an asynchronous request. To create an asynchronous request you just have to add one or more event handlers to the events provided by the XmlHttpRequest.

The XmlHttpRequest class provides the following events to assign event handlers (callback functions) to:

Event Description
onOpened Fired when the internal XMLHttpRequest object's open() method has been executed.
onSent Fired when the internal XMLHttpRequest object's send() method has been executed and headers have been received.
onReceiving Fired when data load is in transer.
onComplete Fired when data load has finished.
onSucceed Fired when data load has finished and status code received is any value between 200 and 299 (= success).
onFail Fired when data load has finished and status code received is less than 200 or greater than 299.

So, to create an asynchronous call, use code similar to the following:

var xml = new AxelDahmen.XmlHttpRequest(); xml.onSucceed = function() {alert("Transfer successfully accomplished!");} xml.send("http://www.contoso.com/sample.cgi", xml.type.GET);

You may optionally want add some HTTP request headers to the request. To do so, add arbitrary string properties to the XmlHttpRequest object:

var xml = new AxelDahmen.XmlHttpRequest(); xml["If-Modified-Since"] = new Date(new Date() - 1).toUTCString(); xml.send("http://www.contoso.com/sample.cgi", xml.type.GET);

If you need to access a resource that's being secured by restricting access to registered users only, you may optionally add user information to the HTTP request:

var xml = new AxelDahmen.XmlHttpRequest(); xml.send("http://www.contoso.com/sample.cgi", xml.type.GET, "MyUserName", "MyPassword");

Alternatively you can provide user information along with the URL:

var xml = new AxelDahmen.XmlHttpRequest(); xml.send("http://MyUserName:MyPassword@www.contoso.com/sample.cgi", xml.type.GET);

If you want to issue a POST HTTP request or a PUT HTTP request, you usually add data to the request sent to the web server. The most common format to upload data using a POST HTTP request or a PUT HTTP request is by adding form parameters in the body of the message just like you would to in a GET HTTP message's query string section.

The XmlHttpRequest library provides a special PostData class to use for adding POST data to the POST HTTP request or a PUT HTTP request. The easiest way to add POST data to your request is by simply creating a PostData object, providing its constructor with an arbitrary object consisting of properties to be used as POST data name/string value pairs and assign this object to the postData property of the XmlHttpRequest object:

var xml = new AxelDahmen.XmlHttpRequest(); var pd = {familyName:"Dahmen", firstName:"Axel"}; xml.postData = new AxelDahmen.XmlHttpRequest.PostData(pd); xml.send("http://www.contoso.com/sample.cgi", xml.type.POST);

If you need to use an encoding different from "application/x-www-form-urlencode" you can create your own Encoding object, providing the MIME type of the encoding used and a function to convert the post data name/value pair object into a string and return that string:

var xml = new AxelDahmen.XmlHttpRequest(); var mimeType = "application/x-www-form-urlencode"; var pd = {familyName:"Dahmen", firstName:"Axel"}; var encFunc = function(postData) { retVal = []; for (var prop in postData) if (typeof postData[prop] == "string") retVal.push((encodeURIComponent(prop) + "=" + encodeURIComponent(postData[prop])).replace("%20", "+")); // return POST data to be sent to the server return retVal.join("&"); } var encoding = new AxelDahmen.XmlHttpRequest.PostData.Encoding(mimeType, encFunc); xml.postData = new AxelDahmen.XmlHttpRequest.PostData(pd, encoding); xml.send("http://www.contoso.com/sample.cgi",xml.type.POST);

To retrieve the content requested by the HTTP request, use the getResponse() method. If the HTTP request was successful, this function returns

If the HTTP request was unsuccessful, this function returns null.

The HTTP resonse header can also be retrieved by the XmlHttpRequest class. Just call the getResponseHeaders() method to retrieve an object consisting of name/value pairs representing the HTTP headers returned by the HTTP request.

Here's an example of how to use the getResponse() and getResponseHeaders() methods:

var xml = new AxelDahmen.XmlHttpRequest(); var content, headers; // synchronous call content = xml.send("http://www.contoso.com/sample.cgi", xml.type.GET); headers = xml.getResponseHeaders(); // ... // asynchronous call xml.onSucceed = function() {alert("Transfer successfully accomplished!");} xml.send("http://www.contoso.com/sample.cgi", xml.type.GET); content = xml.getResponse(); headers = xml.getResponseHeaders(); // convert the headers return value into a string var str = ""; if (headers) for (var head in headers) str += head + ": " + headers[head];

Furthermore, the XmlHttpRequest class provides auxiliary features like:

Item Description
abort() Aborts a pending asynchronous HTTP request.
getStatus() Returns the HTTP status received after HTTP request has been sent.
getStatusText() Returns the HTTP status text received after HTTP request has been sent.
errorHandler(message) May be overridden. Default implementation displays alert() box displaying error description.
version Version number of this library.
type Enumeration providing a list of HTTP methods supported by the XmlHttpRequest object.
HTTP verbs currently supported are: GET, POST, HEAD, OPTIONS, PUT, DELETE.

Additional Shortcut Functionality

To ease most common simple Ajax scenarios, you can use two shortcut functions of the XmlHttpRequest library: get() and post().

Using these two functions you can perform Ajax operations with a single function call.

Here is an example of how to use the get() method to issue an asynchronous HTTP request:

xml.get( "http://www.contoso.com/sample.cgi" , function() { document.getElementById("output").innerHTML = this.getResponse(); if (this.getStatus() == 200) alert("Transfer successfully accomplished!"); } );

And this is an example of how you can use the post() method to issue an asynchronous HTTP request:

xml.post( "http://www.contoso.com/sample.cgi" , function() {alert("Transfer successfully accomplished!");} , {familyName:"Dahmen", firstName:"Axel"}; );

Sometimes it can be easier for you to read your code if the HTTP POST data is preceeding the onComplete event in the post() function call. Therefore, you can alternatively use the HTTP POST data as the second and the onComplete function as the third parameter in a call to the post() function:

xml.post( "http://www.contoso.com/sample.cgi" , {familyName:"Dahmen", firstName:"Axel"}; , function() { document.getElementById("output").innerHTML = this.getResponse(); if (this.getStatus() == 200) alert("Transfer successfully accomplished!"); } );

To boil down get() and post() calls even more, you can provide their function arguments immediately to the XmlHttpRequest constructor function, by using the XmlHttpRequest constructor function as a standard function call, i.e. without the new operator.

If you call the XmlHttpRequest constructor function as a standard function, function arguments decide which action is going to be performed and what kind of result will be returned:

Arguments Description Return Value
none * Creates a new XmlHttpRequest object. The new created XmlHttpRequest object.
XmlHttpRequest.PostData or anonymous object * Creates a new XmlHttpRequest object and sets postData member to provided data. The new created XmlHttpRequest object.
get() function arguments Creates a new XmlHttpRequest object and executes the get() function with provided arguments. Result of the get() call.
post() function arguments, incl. HTTP POST data (required) Creates a new XmlHttpRequest object and executes the post() function with provided arguments. Result of the post() call.

* Accepted when used with the new operator as well.

So, creating a HTTP GET call, your code may actually boil down to something like:

var response = XmlHttpRequest("http://www.contoso.com/sample.cgi");

or:

XmlHttpRequest( "http://www.contoso.com/sample.cgi" , function() { document.getElementById("output").innerHTML = this.getResponse(); if (this.getStatus() == 200) alert("Transfer successfully accomplished!"); } );

And creating a HTTP POST call may become as easy as this:

var response = XmlHttpRequest( "http://www.contoso.com/sample.cgi" , {familyName:"Dahmen", firstName:"Axel"}; );

or:

XmlHttpRequest( "http://www.contoso.com/sample.cgi" , {familyName:"Dahmen", firstName:"Axel"}; , function() { document.getElementById("output").innerHTML = this.getResponse(); if (this.getStatus() == 200) alert("Transfer successfully accomplished!"); } );

Notes

The XmlHttpRequest library was inspired by the information given in the georgeous book JavaScript: The Definitive Guide, by David Flanagan, 5th edition, O'Reilly Media.

It currently doesn't make use of the JQuery library but should be compatible with it.


Axel Dahmen Soft- and Hardware-Engineering
02/19/2010 11:05