AJAX

OK. I've been wanting to write an article about the myriad wonders of Ajax almost since I first found out about it. Ajax is a very powerful and flexible technology (almost as good as XML :P), and I love raving about it. I've just found some time to write this article; I'm currently rather depressed with some work I've been doing for the past 8 hours, so I thought now was as best a time as any to sit down and spout. :)

Ajax is one of the most flexible technologies to come to fruition since the birth of the web. It's actually been around for quite a while, but lack of widespread browser support, and developer ignorance have kept it at bay. It's basically just a simple application of Javascript to download new data and utilise it, without actually reloading the whole page. This allows developers to keep server load down; load data unbelievably quickly make some snazzy interfaces; and generally impress the users: Ajax is a flashy technology.

So, on to the actual code.

The implementation of Ajax is rather simple - all the data is transferred using XML packets:

  • The transaction is initiated from the client-side, using Javascript
  • The Javascript uses an XMLHttpRequest object (or equivalent) to fetch a page from the server (typically from a dynamic script)
  • It sets an "onreadystatechange" function to catch the response, and then exits
  • The "onreadystatechange" function catches the response from the server, and parses the XML
  • It then dynamically calls the respective function to deal with the actual data received

var req;

function load_XML_doc(url)
{
if(window.XMLHttpRequest)
{
//Branch for decent browsers' XMLHttpRequest object
req=new XMLHttpRequest();
req.onreadystatechange=process_req_change;
req.open("GET",url,true);
req.send(null);
}
else if(window.ActiveXObject)
{
//Branch for IE :(
req=new ActiveXObject("Microsoft.XMLHTTP");
if(req)
{
req.onreadystatechange=process_req_change;
req.open("GET",url,true);
req.send();
}
}
}

This function is called on the client-side when you want to initiate an Ajax transaction. It requests a document from the server, sets a function to catch the response, then disappears. It uses different methods of communication for different browsers (Gecko / MSIE), but the end result is still the same.

function process_req_change()
{
//If req is 'complete'
if(req.readyState==4)
{
//If status is 'OK'
if(req.status==200)
{
//Process the result
response=req.responseXML.documentElement;

var method=response.getElementsByTagName("method")[0].firstChild.data;
var result=response.getElementsByTagName("result")[0].firstChild.data;
var resultpos=response.getElementsByTagName("resultpos")[0].firstChild.data;
resultpos--;

var eval_text=method+"(";
for(var i=0;i<resultpos;i++)
{
eval_text=eval_text+"'',";
}
eval_text=eval_text+"result);";

eval(eval_text);
}
else
{
alert("There was a problem retrieving the XML data:n"+req.statusText);
}
}
}

This function receives the XML data packet sent by the server, extracts the useful data, and calls the right function to handle said data. Note that the XML handling is all done through the DOM. No IE-only old methods for Ajax. ;)

This is all fine and well...but without the XML data format, everyone's a bit stuck:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<method>get_databases</method>
<result></result>
<resultpos>5</resultpos>
</response>

There are three main points of interest here:

  • The "method" tag: it contains the name of the Javascript function that will handle the returned data
  • The "result" tag: it contains the actual data to be used
  • The "resultpos" tag is my own addition: if you want to have the contents of the "result" tag passed to the "method" Javascript function in some parameter position other than 1, set it here. ;)

This data has to be sent with a certain MIME type ("text/xml"). The following PHP code will achieve that:

header('Content-Type: text/xml;charset=iso-8859-1');
header('Vary: Accept');

So, we have two abstract functions for dealing with XML-RPC, a format for the XML data packets, and a snippet of PHP for header manipulation. Time to write a sample Javascript function to actually call something!

function get_message(message_number,response)
{
if(response!='')
{
//Deal with the response
window.alert("Received message: "+response);
}
else
{
//Make the query!
var url="sample.php?message_number="+message_number;
load_XML_doc(url);
}
}

This function is exceedingly simple, but it manages to deal with the sending and handling of the data.

Coupled with a PHP script ("sample.php"):

<?php
header('Content-Type: text/xml;charset=iso-8859-1');
header('Vary: Accept');

echo '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<response>
<method>get_message</method>
<result>';

switch($_GET['message_number'])
{
case 1:
echo 'Hello world!';
case 2:
echo 'Goodbye world.';
default:
echo 'Unknown message_number.';
}

echo '</result>
<resultpos>2</resultpos>
</response>';
?>

That should work, and give you a nice little spiced up "Hello world" script - using Ajax

To make things a little friendlier for the user, you could use DOM manipulation to place results in the page dynamically.

For some neat (even if I do say so myself!) examples of Ajax in action, see Helios :D

One thought on “AJAX

Comments are closed.