Every Wednesday at Cake we have sessions where one of us has the opportunity to present an emerging technology. Today was my turn. With my experience in AJAX and all things Web 2.0 it was the natural choice to give the Cake team a rundown on AJAX.
AJAX stands for Asynchronous JavaScript and XML. It is asynchronous to the extent of the JavaScript does all the requesting, loading, parsing of the XML in the background or “behind the scenes” without the disturbance of the display of the existing page.
Due to it’s very nature it offers advantages over non-AJAX web applications.
- Gives a richer user experience – create desktop-like applications
- Makes use of existing functionality and business logic i.e. DRY code, no need to write the same functionality again in JavaScript
- Lower bandwidth usage as data only is sent, rather than the accompanying style and layout
So how does it work?
First you need an instance of the XMLHttpRequest object. This in turn sends request for the XML (HTML, JSON or plain text also) file. The XML file could be served from a data service e.g. outputted by server-side scripting, a file system or some proxy or pooling service.
An instance where you’d need a proxy or pooling service is where the XML data, say an RSS feed, is hosted on another domain. Browser security settings prohibit JavaScript from accessing XML data from another domain as it could initiate a XSS attack. Say you trust the domain you are acquiring the XML data from, you need to create a proxy on your domain. In PHP a simple proxy could be made using the following code:
<?PHP
header('Content-Type: text/xml');
$xml_url = "http://www.cakesolutions.net/teamblogs/feed/";
if($xml_url) print implode(file($xml_url));
?>
Note that when you do serve an XML file from a server-side script be sure that you send the correct mime-type (text/xml in the case of XML) in the Content-Type response header. Some browsers are more forgiving than others but for your AJAX application to work in all browsers you should include the correct Content-Type. That would be the best practice anyhow.
So do you create an XMLHttpRequest object?
In an ideal world the JavaScript would be as follows:
var xmlHttp = new XMLHttpRequest();
Unfortunately, when it comes to standards, the browser world is far from ideal. We have to do this:
try {
//Firefox,Safari and Opera
xmlHttp = new XMLHttpRequest();
}
catch(e)
{
//Internet Explorer
try {
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
//Handle xmlHttp state changes
//Syntax .onreadystatechange = function;
xmlHttp.onreadystatechange = <Some Function>;
In the first example we see an image gallery. Note that there are HTML elements and content surrounding the gallery are the same even when you click through to image 2 and 3. It is pointless sending all these HTML elements and content again using up precious bandwidth and loading it all again in the browser, so lets use our new AJAX skills to load an XML with the sources and descriptions and change them dynamically. This is what Facebook does in their albums. Check out the following example. The image sources and descriptions are contained within the images.xml and the JavaScript is contained with in ajax.js. Note in this implementation that we are not creating a new HTML page or even changing the link sources, if JavaScript is switched off it will still work. The initializeClick function returns false, telling the browser not to load the linked page. Hence no unnecessary loading of pages as we already have loaded the XML when HTML document loads.
Once again, implementing functionality in JavaScript can be problematic due to the various incarnations of the implementation of JavaScript in browsers and the lengths one needs to go to to get the information one wants. You’ll find yourself after having spent time debugging your script in Firefox, you try it in Internet Explorer and it’s broken. One way to avoid the headache of cross-browser compatibility is to use a framework.
jQuery has been my framework of choice for some time. It enables you to write your JavaScript code only once and you’ll be able to have the assurance that it will work in most browsers. jQuery has a Test Suite that has 1157 tests to check browser compatibility. All modern browsers pass the test. This also is a great way to benchmark the performance of each browser’s implementations of JavaScript.
Looking at the example again but this time using jQuery, we see that the implementation takes fewer lines of code hence jQuery’s mantra Write less, Do more.
You can also use CSS like selectors:
$("div") // returns all div elements
$(".class") // returns all elements with the class .class i.e. class="class"
$("#id") // returns the element with the id #id i.e. id="id"
Selecting elements by class is a very handy. If you like to do things properly, with valid markup, you will know that you can have multiple elements with the same class, whereas you cannot have more than one element with the same id. At the moment there are no native implementation of document.getElementsByClassName(). Using a framework’s implementation not only allows you to the functionality now but rest assured with later incarnations of the framework it’ll utilize the native functions, thus your code is backwardly compatible and future proof!
On to our next example, using jQuery. We have a sign up form that on certain events (See signup_check.js) will trigger an AJAX call to a service with has some logic contained within it. This in turn will output XML and a message will be displayed.
In the case of the Username field once the user has tabbed/clicked out of the input box (blur) it posts the parameter user to the user.php where the checks go on. The responses are as follows.
//If the user exists already
<message>
<type>error</type>
<text>Username already taken</text>
</message>
//If the user does not exist
<message>
<type>notice</type>
<text>Username available</text>
</message>
In the case of the Password field once the user has entered more than four characters it posts the parameter password to the strength.php to see whether if the password is strong or not. The responses are as follows.
//If all lowercase, uppercase or numbers
<password_strength>
<stength>weak</strength>
</password_strength>
//else
<password_strength>
<stength>strong</strength>
</password_strength>
Then the utilization of jQuery’s DOM manipulation functionality is used to process and output the XML data in the existing HTML document’s DOM.
Remember that a good AJAX application is a good non-AJAX application. When JavaScript is switched off your application should still work. It may not have all the fancy DOM transitions or the rich desktop-like experience but the functionality should still remain, the links should work, the server side part of the application should be able to deal with the data, error handle and do all things you’d expect from the AJAX version. First build your application without AJAX, then add additional AJAX functionality, then, your web application will be truly accessible to all.
Download the source zip tar.gz
Download the Quicktime presentation (Preview: YouTube)
Tags: AJAX, Browser compatibility, Javascript, jQuery, XML, XSS