The term AJAX is a pseudo-acronym for "Asynchronous JavaScript And XML," (see Ajax: A New Approach to Web Applications) 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.
Although it is not uncommon to see the term written in all capital letters (AJAX), it has become standard to write it as Ajax.
XMLHttpRequest object.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.



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.




All this is accomplished without having to do even one complete refresh. This is the major benefit of Ajax.
Like this Ajax tutorial? Try our self-paced online Ajax courses, which includes videos and exercises in addition to the content in this Ajax tutorial. Not sure if you want to pay for that? Register for a free demo of the course.
The mechanism for sending data to and retrieving data from the server with Ajax is the XMLHttpRequest object. Until HTML5, the XMLHttpRequest Object wasn't officially part of any common specification; however, all the major browsers have supported it for some time.
The HTML5 method is straightforward. It uses a simple XMLHttpRequest() constructor to create the object.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="../../lib.js"></script>
<script type="text/javascript">
function start() {
if (window.XMLHttpRequest) {
var xmlhttp = new XMLHttpRequest();
document.getElementById("Content").innerHTML =
"<h1>Using XMLHttpRequest Object</h1>";
} else {
var xmlhttp = false;
document.getElementById("Content").innerHTML =
"<h1>XMLHttp cannot be created!</h1>";
}
}
observeEvent(window,"load",function() {
var btn=document.getElementById("btnStart");
observeEvent(btn,"click",start);
});
</script>
<title>XMLHttpRequest - HTML5 Method</title>
</head>
<body>
<button id="btnStart">Start</button>
<div id="Content"></div>
</body>
</html>
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!"
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.
| Argument | 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);
Although the HTTP specification identifies several methods of HTTP requests
, the most commonly supported (and used) methods are GET, POST and 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.php",true);
And the response might look like this:
Date: Wed, 11 May 2011 15:46:30 GMT X-Powered-By: ASP.NET Content-Length: 63 Last-Modified: Tue, 10 May 2011 19:12:27 GMT Server: Microsoft-IIS/7.5 ETag: "712b13346fcc1:0" Content-Type: text/xml Accept-Ranges: bytes
The XMLHttpRequest request is sent as follows:
xmlhttp.send(null);
We'll explain why null is passed in just a moment.
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.php?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 simple text, JSON, HTML or XML.
Again, the XMLHttpRequest request is sent as follows:
xmlhttp.send(null);
The POST method is used to send information as an enclosed entity. The call would look like this:
xmlhttp.open("POST","Demo.php",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.
Data cannot be sent in this manner with the HEAD and GET methods, which is why null was passed in the previous examples.
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.
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.
The xmlhttp object's readyState property holds
the current state of the response. There are five possible states (0-4),
which are described below. Browsers do not necessarily inform you of
all states; states 0 and 3 in particular may not appear when you run
the demo file.
| State | Description |
|---|---|
| 0 | uninitialized |
| 1 | loading |
| 2 | loaded |
| 3 | interactive |
| 4 | complete |
Each change in the readyState is captured by the xmlhttp object's onreadystatechange event handler. We can assign a callback function to this property like this:
xmlhttp.onreadystatechange = function() {
//Do something here
}
This use of an anonymous or unnamed 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 like this:
xmlhttp.onreadystatechange = handler;
The following sample file illustrates how the readystatechange event is handled.
---- C O D E O M I T T E D ----
<script type="text/javascript">
function start() {
var xmlhttp = new XMLHttpRequest();
var contentDiv = document.getElementById("Content");
xmlhttp.open("HEAD", "Demo.xml", true);
xmlhttp.onreadystatechange=function() {
contentDiv.innerHTML +=
"Ready State: " + xmlhttp.readyState + "<br>";
}
xmlhttp.send(null);
}
---- C O D E O M I T T E D ----
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.
| 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. |
| 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(postData)
|
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 (200) and then to output the message body to a div on the HTML page. The following sample file demonstrates this:
---- C O D E O M I T T E D ----
function start() {
var xmlhttp = new XMLHttpRequest();
var contentDiv = document.getElementById("Content");
xmlhttp.open("GET", "Demo.php?FirstName=Nat&LastName=Dunn", true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
contentDiv.innerHTML=xmlhttp.responseText;
}
}
xmlhttp.send(null);
}
---- C O D E O M I T T E D ----
This page simply "copies" the response text (xmlhttp.responseText) and "pastes" it into the "Content" div on the page.
Like this Ajax tutorial? Try our self-paced online Ajax course, which includes videos and exercises in addition to the content in this Ajax tutorial. Not sure if you want to pay for that? Register for a free demo of the course.
In the demos thus far, we have used anonymous callback functions to handle the Ajax response, like so:
xmlhttp.onreadystatechange=function() {
//handle response
}
As these anonymous functions are nested within the original function, they have access to the variable set in the original function. That's why we can reuse the xmlhttp and contentDiv variables within the callback function:
function start() {
var xmlhttp = new XMLHttpRequest();
var contentDiv = document.getElementById("Content");
xmlhttp.open("POST", "Demo.php", true);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
contentDiv.innerHTML=xmlhttp.responseText;
}
}
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xmlhttp.send("FirstName=Nat&LastName=Dunn");
}
But callback functions don't have to be anonymous or nested. Another way to write this is shown below:
var xmlhttp = new XMLHttpRequest();
var contentDiv = document.getElementById("Content");
function start() {
xmlhttp.open("POST", "Demo.php", true);
xmlhttp.onreadystatechange=myCallBack;
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xmlhttp.send("FirstName=Nat&LastName=Dunn");
}
function myCallBack() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
contentDiv.innerHTML=xmlhttp.responseText;
}
}
The problem with this method is that it uses global variables. This can be problematic as the variables can easily be unintentionally and unexpectedly overwritten. One way around this is to use an anonymous callback function to make the call to the now-pseudo-callback function and pass the necessary variables into it, like this:
function start() {
var xmlhttp = new XMLHttpRequest();
var contentDiv = document.getElementById("Content");
xmlhttp.open("POST", "Demo.php", true);
xmlhttp.onreadystatechange=function() {
myCallBack(xmlhttp, contentDiv);
};
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xmlhttp.send("FirstName=Nat&LastName=Dunn");
}
function myCallBack(xmlhttp, contentDiv) {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
contentDiv.innerHTML=xmlhttp.responseText;
}
}
Another way to handle it is to nest a named callback function within the original function. As JavaScript functions are objects, they can have their own methods, so you can do the following:
function start() {
var xmlhttp = new XMLHttpRequest();
var contentDiv = document.getElementById("Content");
xmlhttp.open("POST", "Demo.php", true);
xmlhttp.onreadystatechange=myCallBack;
xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xmlhttp.send("FirstName=Nat&LastName=Dunn");
function myCallBack() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
contentDiv.innerHTML=xmlhttp.responseText;
}
}
}
Because the callback function is nested within the start() function, it has access to the xmlhttp and contentDiv variables. The only limitation of this method is that the myCallBack() function is not callable from outside the start() function. Depending on what you're trying to do, that may or may not be an issue.
Like this Ajax tutorial? Try our self-paced online Ajax course, which includes videos and exercises in addition to the content in this Ajax tutorial. Not sure if you want to pay for that? Register for a free demo of the course.
This page was last updated on 2013-01-03
All pages and graphics in this Ajax Tutorial is copyright 2013 and are the property of Webucator, Inc. unless otherwise specified. The purpose of this website is to help you learn Ajax on your own and use of the website implies your agreement to our Terms of Service.