Ajax and XMLHttpRequest

This tutorial demonstrates and describes how to use the XMLHttpRequest object to initiate Ajax requests, and how to handle responses from the server. The XMLHttpRequest object is supported by all current browsers.[1]

Here is our function for initiating and handling Ajax requests and responses:

/* dw_makeXHRRequest function
 * required arguments: url, callback
 * optional arguments: method, postData, and dataType
 */
function dw_makeXHRRequest( url, callback, method, postData, dataType ) {
    if ( !window.XMLHttpRequest ) {
        return null;
    }
    
    // create request object
    var req = new XMLHttpRequest();
    
    // assign defaults to optional arguments
    method = method || 'GET';
    postData = postData || null;
    dataType = dataType || 'text/plain';
    
    // pass method and url to open method
    req.open( method, url );
    // set Content-Type header 
    req.setRequestHeader('Content-Type', dataType);
    
    // handle readystatechange event
    req.onreadystatechange = function() {
        // check readyState property
        if ( req.readyState === 4 ) { // 4 signifies DONE
            // req.status of 200 means success
            if ( req.status === 200 ) {
                callback.success(req); 
            } else { // handle request failure
                callback.failure(req); 
            }
        }
    }
    
    req.send( postData ); // send request
    
    return req; // return request object
}

We provide GET, POST, and JSON examples that demonstrate the above function.

The dw_makeXHRRequest Function Described

First we check for browser support at the top of the function and return null if the XMLHttpRequest object is not supported. Then we invoke the XMLHttpRequest constructor to create a request object.

The method, postData, and dataType arguments are not required, so we initialize them with defaults. The default method is GET. If the request is a POST, method, postData, and dataType are passed to the function. The dataType for a POST request may be 'application/x-www-form-urlencoded', or if the values passed in the Ajax request are JSON formatted, the dataType would be 'application/json'. We demonstrate below how each request type calls the dw_makeXHRRequest function.

The url argument specifies the destination for the Ajax request (path and file name). The callback argument consists of an object which includes methods for handling success and failure of the request. Read more about the callback object below.

URL and request method are passed to the XMLHttpRequest object's open method. The setRequestHeader method is used to specify a Content-Type matching dataType.

The function assigned to the request object's onreadystatechange event first checks the readyState property which is set 4 signifying DONE when either the response has been received or something went wrong. The request status property is then checked to determine the HTTP status code. A value of 200 indicates success; other values indicate failure.[2] The request object (req) is passed to the functions assigned to handle success and failure as discussed below.

Finally, the request object's send method is invoked, and the request object is returned to the calling function.

Using the dw_makeXHRRequest Function

The arguments passed to the dw_makeXHRRequest function vary with the type of request and the type of data being passed. To demonstrate each type, we provide the following simple object literal:

// variable for example Ajax requests
var data = {
    firstName: 'Jon',
    lastName: 'Smith',
    age: 24
};

GET and POST examples show how to assemble data for Ajax requests from form entries.

Invoking dw_makeXHRRequest for a GET Request

GET requests pass data to the server in the URL query string. The data must be properly encoded. We provide the dw_encodeVars function displayed below for this purpose. When calling the dw_makeXHRRequest function for a GET request, pass the URL (with the encoded data in the query string), and the callback object described below.

// Invoking dw_makeXHRRequest for a GET Request
dw_makeXHRRequest('get.php?' + dw_encodeVars(data), callback);

See an example demonstrating how to set up an Ajax GET request.

Invoking dw_makeXHRRequest for a POST Request

A POST request includes the data in the body of the request rather than in the URL. If the POST request is to emulate a regular form submission, the data type would be specified as 'application/x-www-form-urlencoded', and the dw_encodeVars function would be used to encode the data. The call to dw_makeXHRRequest would include the URL, callback object (described below), request method (POST), encoded data, and data type arguments:

// Invoking dw_makeXHRRequest for a POST Request
dw_makeXHRRequest('post.php', callback, 'POST', dw_encodeVars(data),
                  'application/x-www-form-urlencoded');

See an example demonstrating how to set up an Ajax POST request.

Invoking dw_makeXHRRequest when passing JSON to PHP

JSON data passed in an Ajax request would use the POST method and the data type 'application/json'. The JSON.stringify method would be applied to the data to convert it to valid JSON. The URL, callback object (described below), method, stringified data, and data type arguments would be passed in the call to dw_makeXHRRequest:

// Invoking dw_makeXHRRequest to pass JSON to PHP
dw_makeXHRRequest('json.php', callback, 'POST', JSON.stringify(data),
                  'application/json');

An example demonstrates how to use JSON with Ajax. See also more information about JSON.stringify.

Handling Ajax Request Success and Failure

When you call the dw_makeXHRRequest function to initiate an Ajax request, you pass a callback object which provides success and failure methods. When the dw_makeXHRRequest function invokes one of these methods, it passes the request object (req), providing access to its properties:

// excerpt from dw_makeXHRRequest, readystatechange handler
function dw_makeXHRRequest( url, callback, method, postData, dataType ) {
    // ...
    
    req.onreadystatechange = function() {
        // ...
        if ( req.status === 200 ) {
            callback.success(req); 
        } else { // handle request failure
            callback.failure(req); 
        }
    
    // ...
}

This allows you to specify what should happen in your own code upon the conclusion, successful or otherwise, of an Ajax request. GET, POST, and JSON examples all show how to set up the callback object with its success and failure methods.

Encoding Data Passed in Ajax Requests

Name-value pairs, whether from JavaScript objects or HTML form entries, must be properly encoded for passage to the server using Ajax. The following function is provided for this purpose:

function dw_encodeVars(params) {
    var str = '';
    for (var i in params ) {
        str += encodeURIComponent(i) + '=' + encodeURIComponent( params[i] ) + '&';
    }
    return str.slice(0, -1);
}

The dw_encodeVars function accepts an object as an argument. (The examples above demonstrate its use with the data object literal provided. GET and POST examples show how to create an object literal using form element names and values.)

The dw_encodeVars function loops through the properties in the object passed to it and applies the JavaScript encodeURIComponent function to each property name and value. The function builds a string that separates name from value with an equals sign and each name-value pair from the next with an ampersand. The string returned from dw_encodeVars can then be included in the URL of a GET request, or in the body of a POST request with the data type 'application/x-www-form-urlencoded'.

Ajax Examples

Examples demonstrate how to use the dw_makeXHRRequest function for GET, POST, and JSON. Although the online examples are not functional, those in the download file are.


  1. The XMLHttpRequest object is supported by Internet Explorer as of version 7. ^
  2. See the W3C XMLHttpRequest Specification for details on properties of the XMLHttpRequest object. ^