Welcome to our free Advanced JavaScript Programming tutorial. This tutorial is based on Webucator's Advanced JavaScript Programming course.
Let's review the underlying code to see how the actual Ajax calls and response-handling work. 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.
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",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?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",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;charset=UTF-8"); 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;charset=UTF-8". 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 }
In JavaScript, as we have seen, 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 } }
Of course, the real power of using the XMLHttpRequest
object is to consume resources from another page, from an external feed, from a database, etc., which we aren't doing in our simple examples above. To perform more interesting tasks using the XMLHttpRequest
object, we'll need to run files from a local web server. A little later we'll cover how you can set up a Node.js server on your local computer.
This tutorial is based on Webucator's Advanced JavaScript Programming Course. We also offer many other JavaScript Training courses. Sign up today to get help from a live instructor.