Kaye and Geoff's web page documentation 

Introduction

AJAX (Asynchronous JavaScript + XML) is a collection of web technologies which together allow web pages to display content dynamically, typically in response to user input. Ajax builds on a number of pre-existing web features, so to use Ajax, in addition to HTML you need to understand something about the document object model (DOM), the HTTP protocol, Javascript and CGIs, and maybe XHTML.

Why might you want to use Ajax? Consider a link, or maybe the "action" parameter of a form, which points to a CGI. When the link is taken, the server invokes the CGI which must ultimately return a web page or a reference to a web page. To look at it from a more fundamental point of view, the browser makes an HTTP request and receives an HTTP response (which is normally the web page to be displayed). With Ajax the process is similar, except that the request is initiated, and the response received and acted upon, by Javascript code. The big difference is that a new page is not loaded, the returned data does not have to include all the information required for a complete web page, and there is more flexibility in how the response can be handled. So the new information appears faster and can be displayed in a consistent context.

The examples on this page are simplified to make them as easy as possible to understand, so they do not include lots of validation and error checking. They work with reasonable input, but if you give them extreme or meaningless values they will probably return meaningless results.

And remember that this is just an overview of Ajax - there are lots of detailed tutorials on the web which should be consulted if you want to learn all there is to know about it. You could, for example, try some of the links at the end of the page. On the other hand, if you just want a general description of Ajax and to see it in action then you can read this page without paying too much attention to the example code.

A simple example - date and time

There is a significant amount of underlying complexity even with an apparently simple Ajax example such as the one below, which just displays the time and date. Since Javascript has direct access to the date and time, using Ajax for the task is like using a steamroller to crack a walnut, but it serves to introduce the methodology. To emphasise the similarity between "regular" CGI access and Ajax, you can try both - the CGI running on the server which responds to the request is the same, the difference is in how the results are displayed.

    the result is: 

Note that the time and date displayed are the values for the region in which the server is located (USA) rather than local ones (which you would get if you asked Javascript to provide them directly).

Here is the HTML for this example.

<form name="form11" action="http://www.kgweb.org.au/cgi-bin/ajax/ajax_date.pl" method="post" target="_blank"> <input type="submit" value="Test cgi ajax_date.pl without using ajax"> </form> <form name="form12"> <input type="button" value="Test cgi ajax_date.pl using ajax" onClick="sendHttpReq('http://www.kgweb.org.au/cgi-bin/ajax/ajax_date.pl', '', handleDTData)"> &nbsp;&nbsp;&nbsp; <small>the result is:</small>&nbsp; <input type="text" name="field13" size="42"> </form>

There are two forms. The first has an action attribute within the <form> tag and a submit button - a typical method of invoking a CGI. The Ajax form, by contrast, has no attributes other than name in the <form> tag but has a button whose onClick handler is a Javascript function. Clearly all the excitement is in the Javascript code, so here it is:

// general routines to implement AJAX // declare a variable to hold a reference to the http request object
var httpReq;
// function to send data to url // handle browser incompatabilities // globalise the function used to deal with the response // assign the returned data handler // open the request and send the data
function sendHttpReq(url, data, handledata) { if(window.XMLHttpRequest) { httpReq = new XMLHttpRequest(); } else if (window.ActiveXObject) { httpReq = new ActiveXObject('Microsoft.XMLHTTP'); } else { alert ("Failed to insubstantiate request object\n\nAjax not supported?"); return false; } httpReq.dhfunction = handledata; httpReq.onreadystatechange = receiveHttpReq; httpReq.open ("POST", url, true); httpReq.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded"); httpReq.send (data); return true; }
// function to receive the returned data // only if httpReq shows "loaded" [4] and only if "OK" [200]
function receiveHttpReq() { if (httpReq.readyState == 4) { if (httpReq.status == 200) { var returnedata = httpReq.responseText; httpReq.dhfunction(returnedata); } else { alert ("httpReq.status = " + httpReq.status); alert("Failed to retrieve data:\n" + httpReq.statusText); } } }
// function to handle the returned date and time // just display it in a form field
function handleDTData(str) { document.form12.field13.value = str; }

There are three functions here. The first two are general routines which could be used in many different situations - they send a request and receive a response. The third handles the response, and so is specific to the particular application.

To make a request we need the URL of the CGI (say a Perl program, or PHP code) or whatever will handle the request on the server, and the information which the CGI needs to carry out its function. Ultimately we will also need some Javascript code to process the result. So the parameters to sendHttpReq are a string containing a URL, a string containing the input data, and the name of a routine to handle the returned information. This latter routine will be invoked from the function which receives the result, so for convenience we can use the httpRequest object to "store" it for us (code in red).

At the heart of Ajax is the Javascript XMLHttpRequest object. Internet Explorer implements it as an activeX object, so we need two different ways of obtaining a reference to it, but after that the methods and parameters are the same for all browsers. You can see the basic methods and parameters of the httpRequest object which allow us to define a routine to receive the response, open the request, set the HTTP header information and send the request containing the input to the CGI (the code in purple). If the third (boolean) argument to httpReq.open is true then the request is handled asynchonously - this is the preferred approach (hence the 'A' in Ajax) since it makes no assumptions about how long the request may take to be fulfilled and does not halt execution of the process.

A series of 'readystates' are set (and thus invoke the receiveHttpReq function) as the request is processed, culminating in a value of 4 indicating that a response has been returned. However just having a response does not ensure that it is what we expected; a problem may have arisen which meant that the server could not return the information we wanted (for example the CGI may not be found or may generate an error). So we also need to check for the HTTP response code (200) which tells us that the request was successful. When these tests are satisfied we can pass the returned data to our handling routine (in this case handleDTData, which displays it in a form field).

The date and time CGI

To complete the overview of this example, we can now look at the CGI which provides the date and time. In this case it is written in Perl and looks like this:

#! /usr/bin/perl # # cgi to work with ajax - returns date and time # get the current date # return it as the data for an http response with MIME type of plain text # $date = `date`; print "Content-type: text/plain\n\n"; print $date; exit;

Even programmers who are not familiar with Perl should able to follow the code. After some comment lines the system date is read into the variable $date. Anything which is printed goes to standard output which means that it is passed back to the server. The HTTP protocol requires a header which must include a MIME type (Content-type) definition separated from the body by a blank line. In this example the MIME type is text/plain and the body just has the date and time string.

Another simple example - adding two numbers

Before further consideration of the XMLHttpRequest object, we can look at another example. It is not much more complex than the first example, except that it passes information to the CGI. Again, the task would be easier to accomplish using simple Javascript, but then driving a steamroller is more fun than using a nutcracker.

input to CGI (two numbers)   
input to CGI (two numbers)       

The HTML is very similar to that used in the previous example, except that here the CGI is called ajax_add.pl, the data string passed to it is 'f=the value of the form field called field22' and the function to process the data is called handleAddData. Look at the HTML source if you want the exact syntax. We use the 'name=value' (with a dummy name of 'f') for the data string because this is how information is passed to a CGI from a form.

The Perl CGI is quite straightforward; it accepts the input, extracts the numbers, adds them and returns the result as a string (exactly as in the previous example). The Javascript routines used to send and receive the request are the same as for the first example. Function handleAddData displays the returned string, but in this case as regular text inside <span> tags. It looks like this:

function handleAddData(str) { var msg = document.getElementById('msgarea'); text = 'The sum of ' + str; msg.firstChild.nodeValue = text; }

Further consideration of the httpRequest object

We can now consider some more features of the httpRequest object which have so far been ignored or glossed over. In some cases browsers differ in how they implement these features so the discussion below is conservative and describes approaches which should work in all circumstances.

XML

As stated at the beginning, the 'X' in Ajax stands for 'XML', and the name of the httpRequest object is XMLHttpRequest, but otherwise XHTML has not been mentioned in the discussion so far. In the examples above, the information from the CGIs was returned as unformatted text, but it can also be returned as an XML document. In this case, the MIME type in the CGI should be set to text/xml, not text/plain as in our examples, and the response is found in httpReq.responseXML, not httpReq.responseText. Why use XML rather than plain text? Because the Javascript DOM has inbuilt support to process XML documents, and when using Ajax, DOM routines are typically required to display the returned information on the page.

Security issues

The httpRequest object is subject to the security restrictions which are part of Javascript, and these limit how you can organise the files which together make Ajax work. Firstly, a page which contains a reference to XMLHttpRequest should be invoked via HTTP; so accessing the file locally may not work. Secondly, the domain of the page making the request, and of the URL of the script or whatever services the request, should be the same. Note that this rule is often interpreted strictly, to the extent that if the domain is, for example, ajax.com, using www.ajax.com will result in an error. To make things more difficult, the error will probably not be reported explicitly. This is why the

alert ("httpReq.status = " + httpReq.status);

line is included in the receiveHttpReq() function above - it reports zero when a security fault occurs, whereas the statusText reports nothing (it is just blank). If you get a status of zero and you do not think it is a "same origin" security problem, you could try investigating event.preventDefault (it is too involved to discuss in any detail here).

A final example - Freddy and Sally

It is difficult to find an application which could only be achieved using Ajax, but this one would certainly be "messy" without it. Frames have been used to keep everything together, but the process would work the same with two totally independent pages (although note the comments above about security issues).

    

How does it all work? The <iframe> definitions are absolutely standard, loading files called freddy.html and sally.html. When a colour value is entered for Freddy and the background colour changed by clicking on the button, Ajax is used to send the value to a CGI which stores it and returns it. Freddy could ignore the returned value but just for the sake of doing something it is saved back into the form field from which it came. When Sally's button is pressed an Ajax request is sent to the same CGI which reads and returns the current value from the file, which is used by Javascript to change the background colour of Sally's page.

This example again uses the generalised Ajax routines displayed above. The CGI is conceptually simple - when Freddy sends, for example, "freddy=#ff0000", the CGI receives this string, notes that it is from Freddy, opens a text file and writes the hex colour value to it, overwriting any previous data in the file. The CGI then returns the hex value. When Sally sends, for example, "sally=#000000", the CGI notes that it is from Sally and so ignores the colour value, opens the file, reads the hex colour value and returns it.

The Javascript code used by Freddy and Sally to process the response is quite simple; for example Sally's looks like this:

function handleColourData(str) { document.bgColor = str; document.form31.field31.value = str; }

Links for more information

Top
Previous
Index
Home