Ajax Basics

In this lesson of the Ajax tutorial, you will learn...
  1. The Purpose of Ajax.
  2. How Ajax Works.
  3. How to create cross-browser Ajax.
  4. How to send data using Head, Get and Post.

The term AJAX is a pseudo-acronym for "Asynchronous JavaScript And XML," but is now used much more broadly to cover all methods of communicating with a server using JavaScript. As we will see, Ajax is not always asynchronous and does not always involve XML.

The Purpose of Ajax

The main purpose of Ajax is to provide a simple and standard means for a web page to communicate with the server without a complete page refresh. To illustrate this, consider a simple registration form. You have very likely experienced the frustration of having to try multiple usernames when registering for some new website. You fill out the entire form, hit the submit button, wait for a second or so, and then get the same form right back with a message saying that the username you have chosen is not available. You try another easy-to-remember username and find it is also not available. You repeat this several times until finally you pick some obscure username. This process wouldn't be nearly as bad if you didn't have to wait for the entire page to refresh each time you tried a new username.

But that's a very simple example. Some web-based applications require constant interaction with a database through a middle-tier. Take, for example, an interface for updating employee records. The traditional way of doing this is illustrated below.

Traditional Web Application

  1. First, the application shows a list of employees to pick from. (AjaxBasics/Demos/EmployeeAdmin.jsp)
  2. When the user chooses an employee, the server returns a new page (FIRST REFRESH) and a form is displayed. (AjaxBasics/Demos/EditEmployee.jsp)
  3. The user can then edit the employee data (e.g, change "Andrew" to "Andy") and submit the form. The server then returns the new page (SECOND REFRESH). (AjaxBasics/Demos/EditEmployee.jsp)
  4. To get back to the employee list to begin the process of modifying another employee's data, the user would have to click on the "Employee List" link (THIRD REFRESH).

An Ajax Web Application

Ajax makes this process much simpler for the user. Records, and even individual fields of a record, can be edited one at a time without full page refreshes. This method is illustrated below.

  1. Like with the traditional method, the Ajax application shows a list of employees to pick from. (AjaxBasics/Solutions/EmployeeAdmin.html)
  2. When the user chooses an employee, the page doesn't reload. Instead, an Ajax call to the server is made, the server returns the HTML form and JavaScript is used to display the form on the page.
  3. The user can then edit the form fields. Each time a changed form field loses focus the change is sent to the server with Ajax, the server-side code updates the data in the database and sends back the updated list of employees to the browser. JavaScript is again used to display the updated list on the page.
  4. The employee list is updated to reflect the changes made. Notice "Andrew" has been changed to "Andy" in the list. A message is displayed letting the user know that the database was updated.

All this is accomplished without having to do even one complete refresh. This is the major benefit of Ajax.

The XMLHttpRequest Object

The mechanism for sending data to and retrieving data from the server with Ajax is the XMLHttpRequest object. Unfortunately, modern browsers that support XMLHttp requests have different methods for doing so. We'll examine the Mozilla method and the Internet Explorer method and then we'll abstract both methods with a single user-defined function.

Creating an XMLHttpRequest Object

Mozilla Method

The Mozilla method is the most straightforward of the two. It uses a simple XMLHttpRequest() constructor to create the object.

Code Sample: AjaxBasics/Demos/CreateXMLHttpRequest-moz.html

<html>
<head>
<title>XMLHttpRequest in Mozilla</title>
<script type="text/javascript"> 
function Start()
{
 try
 {
  xmlhttp = new XMLHttpRequest();
  document.getElementById("Content").innerHTML="<h1>Using XMLHttpRequest Object</h1>";
 }
 catch (e)
 {
  document.getElementById("Content").innerHTML="<h1>XMLHttp cannot be created!</h1>";
 }  
}
</script>
</head>
<body>
 <a href="javascript:Start()">Start</a>
 <div id="Content"></div>
</body>
</html>
Code Explanation

This code attempts to create an XMLHttpRequest object using the XMLHttpRequest() constructor. If it succeeds, it writes out "Using XMLHttpRequest Object" to the body of the page. If it fails, it writes out "XMLHttp cannot be created!"

Internet Explorer Method

Microsoft Internet Explorer uses an ActiveX control to implement an XMLHttpRequest object. New and improved versions of this control have been released over time, so our code should check for the latest version available on the user's machine and use that one.

Code Sample: AjaxBasics/Demos/CreateXMLHttpRequest-ie.html

<html>
<head>
<title>XMLHttpRequest in Internet Explorer</title>
<script type="text/javascript">
function Start()
{
 var ieXmlHttpVersions = new Array();
 ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.7.0";
 ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.6.0";
 ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.5.0";
 ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.4.0";
 ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.3.0";
 ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp";
 ieXmlHttpVersions[ieXmlHttpVersions.length] = "Microsoft.XMLHttp";

 var i;
 for (i=0; i < ieXmlHttpVersions.length; i++)
 {
  try
  {
   var xmlhttp = new ActiveXObject(ieXmlHttpVersions[i]);
   document.getElementById("Content").innerHTML="<h1>Using " + ieXmlHttpVersions[i] + "</h1>";
   break;
  }
  catch (exc)
  {
   alert(ieXmlHttpVersions[i] + " not supported.");
  }
 }

 if (typeof xmlhttp == "undefined")
  document.getElementById("Content").innerHTML="<h1>XMLHttp cannot be created!</h1>";
}
</script>
</head>
<body>
 <a href="javascript:Start()">Start</a>
 <div id="Content"></div>
</body>
</html>
Code Explanation

This code creates an array containing the names of all the different versions of Microsoft's XMLHttp ActiveX control, starting with the most recent. It then loops through the array and uses the first available control to create an xmlhttp object. As soon as it finds one, it writes out the version being used to the body of the page. If none of the versions is supported, it writes out "XMLHttp cannot be created!"

Cross-browser XMLHttpRequest Creation

The following code sample combines the previous two in one function that handles XMLHttpRequest creation in both browsers. It first tries the Mozilla method as it's much more likely that Internet Explorer will eventually adopt this method than it is that Mozilla and other browsers will support ActiveX controls.

Code Sample: AjaxBasics/Demos/CreateXMLHttpRequest.html

---- Code Omitted ----
<script type="text/javascript"> function Start() { try { var xmlhttp = new XMLHttpRequest(); document.getElementById("Content").innerHTML="<h1>Using XMLHttpRequest Object</h1>"; } catch(err1) { var ieXmlHttpVersions = new Array(); ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.7.0"; ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.6.0"; ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.5.0"; ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.4.0"; ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp.3.0"; ieXmlHttpVersions[ieXmlHttpVersions.length] = "MSXML2.XMLHttp"; ieXmlHttpVersions[ieXmlHttpVersions.length] = "Microsoft.XMLHttp"; var i; for (i=0; i < ieXmlHttpVersions.length; i++) { try { var xmlhttp = new ActiveXObject(ieXmlHttpVersions[i]); document.getElementById("Content").innerHTML="<h1>Using " + ieXmlHttpVersions[i] + "</h1>"; break; } catch (err2) { alert(ieXmlHttpVersions[i] + " not supported."); } } } if (typeof xmlhttp == "undefined") document.getElementById("Content").innerHTML="<h1>XMLHttp cannot be created!</h1>"; } </script>
---- Code Omitted ----

Using an XMLHttpRequest Object

So, now that we have an XMLHttpRequest object created, what do we do with it? We use it to make HTTP requests. To do so, we initialize the object with the open() method, which takes three arguments.

XMLHttpRequest open() Method Arguments
Method Description
Request Type String. Usually POST, GET, or HEAD
URL String. The URL receiving the request.
Asynchronous Boolean. Whether the request should be made asynchronously (true) or synchronously (false).

A typical open() method call is shown below.

xmlhttp.open("GET","Demo.xml",true);

Request Types

Although the HTTP specification identifies several methods of HTTP requests , the most commonly supported (and used) methods are GET, POST and HEAD.

HEAD

The HEAD method is the least commonly used of the three; however, for simple requests, it can be all you need. It simply returns the meta-information contained in the HTTP headers. The call would look like this:

xmlhttp.open("HEAD","Demo.jsp",true);

And the response might look like this:

Server: Microsoft-IIS/5.1 
X-Powered-By: ASP.NET 
Date: Fri, 03 Mar 2006 17:47:47 GMT 
Content-Type: text/xml 
Accept-Ranges: bytes 
Last-Modified: Fri, 03 Mar 2006 14:07:51 GMT 
ETag: "50c59dccb3ec61:99e" 
Content-Length: 21

The XMLHttpRequest request is sent as follows:

xmlhttp.send(null);

We'll explain why null is passed in just a moment.

GET

The GET method is used to send information to the server as part of the URL. The server returns the same header information that the HEAD method returns, but it also returns the body of the message (i.e, the content of the page). Any name-value pairs to be processed by the receiving page should be passed along the querystring. The call would look like this:

xmlhttp.open("GET","Demo.jsp?FirstName=Nat&LastName=Dunn",true);

The response would be the same as the response shown for the HEAD method followed by the message body, which would typically be plain text, HTML or XML.

Again, the XMLHttpRequest request is sent as follows:

xmlhttp.send(null);

POST

The POST method is used to send information as an enclosed entity. The call would look like this:

xmlhttp.open("POST","Demo.jsp",true);

The response header is somewhat different in that it specifies that the returned content is not cacheable. Like with GET, the message body would typically be plain text, HTML or XML.

The XMLHttpRequest request is sent as follows:

xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xmlhttp.send("FirstName=Nat&LastName=Dunn");

As you can see, with POST, we first need to set the content type to "application/x-www-form-urlencoded;". This tells the server to expect form data. In the send method, we include name-value pairs. These name-value pairs are available to the receiving page for processing.

Nothing can be sent in this manner with the HEAD and GET methods, which is why null was passed in the previous examples.

We'll see later that we can also send data in other formats, such as raw XML, using the POST method.

Asynchronous vs. Synchronous Requests

The asynchronous argument should almost always be set to true. After all, that's the "A" in Ajax. Synchronous calls force the browser to wait for a response from the server before continuing. This leaves the user unable to interact with the browser until the response is complete. Asynchronous requests allow the browser to continue to process code while waiting for a response.

Handling the Response

When using asynchronous calls, we cannot be sure when the response will come, so we must write code that waits for the response and handles it when it arrives. We do this with a callback function. Callback functions are functions that are triggered by some event. In our case, the event we are looking for is a change in the state of the xmlhttp response. This event is captured by the xmlhttp object's onreadystatechange property. We can assign a callback function to this property like this:

xmlhttp.onreadystatechange=function() 
{
 //Do something here
}

The xmlhttp object's readyState property holds the current state of the response. There are five possible states (0-4), which are described below.

Values of the readyState Property
State Description
0 uninitialized
1 loading
2 loaded
3 interactive
4 complete

This use of an inline function may be new to you. In JavaScript, functions are first-class objects and can be assigned to variables or properties of other objects. We could also create a named function and assign that function to xmlhttp.onreadystatechange.

The following sample file illustrates how the readystatechange event is handled.

Code Sample: AjaxBasics/Demos/ReadyStateChange.html

---- Code Omitted ----
function Start() {
---- Code Omitted ----
var ContentDiv = document.getElementById("Content"); if (typeof xmlhttp == "undefined") { ContentDiv.innerHTML = "<h1>XMLHttp cannot be created!</h1>"; } else { xmlhttp.open("HEAD", "Demo.xml", true); xmlhttp.onreadystatechange=function() { ContentDiv.innerHTML += "Ready State: " + xmlhttp.readyState + "<br/>"; } xmlhttp.send(null); } }
---- Code Omitted ----
Code Explanation

The output will look something like this. The actual ready states returned will depend on your setup.

In practice, before doing anything with the xmlhttp response data, we want to make sure the readyState is complete (4), so we put a condition inside our function to check for this:

xmlhttp.onreadystatechange=function() 
{
 if (xmlhttp.readyState==4) 
 {
  //Do something here
 }
}

Now we're ready to do something with the data returned. Before looking at an example, let's take a look at the properties and methods of the xmlhttp object, so we know what's available to us.

XMLHttpRequest Object Properties
Property Description
onreadystatechange Specifies the callback function to be triggered when the ready state changes.
readyState Holds the state of the response.
responseText Holds the message body as a string.
responseXML Holds the message body as an XML object.
status Holds the status code returned from the server (e.g, 200 for success, 404 for page not found, etc.).
statusText Holds the status text returned from the server.
XMLHttpRequest Object Methods
Method Description
abort() Aborts the xmlhttp request.
getAllResponseHeaders() Retrieves the values of all the HTTP headers as a string.
getResponseHeader(header) Retrieves the value of the specified HTTP header as a string.
open(Method,URL,Async) Initializes the XMLHttpRequest object.
send(header) Sends the HTTP request to the server.
setRequestHeader(header,value) Specifies the name and value of an HTTP header.

A common application is to check the status property to make sure that the request was successful and then to output the message body to a div on the HTML page. The following sample file demonstrates this.

Code Sample: AjaxBasics/Demos/UsingXMLHttpRequest-Get.html

---- Code Omitted ----
else { xmlhttp.open("GET", "Demo.jsp?FirstName=Nat&LastName=Dunn", true); xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { ContentDiv.innerHTML=xmlhttp.responseText; } } xmlhttp.send(null); }
---- Code Omitted ----
Code Explanation

This page simply "copies" the response text (xmlhttp.responseText) and "pastes" it into the "Content" div on the page.

Ajax Basics Conclusion

In this lesson of the Ajax tutorial, you have learned the purpose of Ajax and the basic foundation for creating Ajax applications.

To continue to learn Ajax go to the top of this page and click on the next lesson in this Ajax Tutorial's Table of Contents.

Use of this website implies agreement to the following:

Copyright Information

All pages and graphics on this Web site are the property of Webucator, Inc. unless otherwise specified.

None of the content on this website may be redistributed or reproduced in any way, shape, or form without written permission from Webucator, Inc.

No Printing or saving of web pages

This content may not be printed or saved. It is for online use only.


Linking to this website

You may link to any of the pages on this website; however, you may not include the content in a frame or iframe without written permission from Webucator, Inc.


Warranties

This website is provided without warranty of any kind. There are no guarantees that use of the site will not be subject to interruptions. All direct or indirect risk related to use of the site is borne entirely by the user. All code and explanations provided on this site are provided without warranties to correctness, performance, fitness, merchantability, and/or any other warranty (whether expressed or implied).

For individual private use only

You agree not to use this online manual to deliver or receive training. If you are delivering or attending a class that is making use of this online manual, you are in violation of our terms of service. Please report any abuse to courseware@webucator.com. If you would like to deliver or receive training using this manual, please fill out the form at http://www.webucator.com/Contact.cfm.