August 9, 2006

Basic AJAX with XMLHttpRequest Class

You will find other articles relevant to this document in these sections:
Cameron Manderson @ 12:02 pm

There is a lot of buzz going around RIA and Web2.0 these days, and at the heart for HTML this involves AJAX. We use AJAX as a way to make a request via JavaScript and return a response from the server, which can be Text or XML.

The fundamental object we use in AJAX to perform this functionality is the XMLHttpRequest class. This class allows us to create a HTTP request and receive a response from the server. The object as itself is quite basic, and allows you to inject in header variables, such as POST vars, and return back a string or XML (DOM Compliant object) response.

I thought I would quickly provide a quick outline of making a request using this object, that I can build examples off in the future, and hopefully discuss a JavaScript framework I wrote around it to handle calls and relaying the responses to appropriate functions.

Creating XMLHttpRequest Objects

There are a few different way for us to create an XMLHttpRequest object, between IE and Mozilla style browsers. The most effective way to create a XMLHttpRequest would be to create a factory method that returns our XMLHttpRequest object depending on the browsers support. Our method would return NULL if our browser isn’t capable of performing the functionality.

function createXMLHttpRequest() {
  if(window.XMLHttpRequest) {
    try { 
      xmlHttpRequest = new XMLHttpRequest();
    } catch(e) { return null; }
  } else if(window.ActiveXObject) {
    try {
      xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
    } catch(e) {
      try {
        xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) { return null; }
    }
  } else return null;
  return xmlHttpRequest;
}
 

Creating a request

We can now create XMLHttpRequests and instruct them how to perform. Here is an example to make a request using our XMLHttpRequest object:

  xmlHttpRequest = createXMLHttpRequest();
  if( xmlHttpRequest  == null) alert("No XMLHttpRequest available");

  // Make the call
  xmlHttpRequest.open("GET", "http://localhost/myscript/?do=whatever", true);
 
  // Associate the ready state change
  xmlHttpRequest.onreadystatechange = function() { alert("We have a changed state!"); }

  try {
    // Send the Method Data
    xmlHttpRequest.send(null);
  } catch(e) { alert("Send  failed"); }
 

When we create the XMLHttpRequest object and use the send() function we need to specify a “onreadstatechange� function that gets called when the XMLHttpRequest object changes state.

The XMLHttpRequest object has several different properties we can access to retrieve our response.

readyState - Object Status INT

responseText - Response as a String

responseXML - DOM Compatible document object from response

status - HTTP Response Codes (200, 404 etc)

statusText - HTTP Response Code Text

Throughout a request lifecycle of the XMLHttpRequest object, it rotates through the following states:

0: “uninitialized”
1: “loading”
2: “loaded”
3: “interactive”
4: “complete”

We can access the response once the state of the XMLHttpRequest object has reached state “4�.

Changing our above example, we can incorporate the XMLHttpRequest properties to determine our result:

xmlHttpRequest.onreadystatechange = function() { 
  try {
    if(xmlHttpRequest.readyState == 4) {
      if(xmlHttpRequest .status == 200) {
        // We have a successful HTTP request with data
        alert("we received:" + xmlHttpRequest.responseText);
      } else {
        // We have an error
        alert("our call failed:" + xmlHttpRequest.status + " " + xmlHttpRequest.statusText);
      }
    }
  } catch(e) { alert("Unable to determine the state of the call");
}

Security

It is also worth noting that due to JavaScript sandboxing issues, it is necessary to:

a) Check from a HTTP: protocol, not a FILE:

b) Only access the information from the same domain, don’t make a call to a different domain.

Where to from here?

Overall this gives us a very basic framework that we can wrapper and write our own functions around. We can extend the base xmlHttpRequest object to handle functionality such as implementing

  • Event Listeners

  • Timeouts/Abort

In the near future I will post an article with an example of making a request and handling a response.

Share and Enjoy:These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • digg
  • Furl
  • Reddit
  • YahooMyWeb

7 Comments »

  1. Some more good reference material for using AJAX:
    - http://developer.apple.com/internet/webcontent/xmlhttpreq.html
    - http://ajaxpatterns.org/wiki/index.php?title=Main_Page
    - http://en.wikipedia.org/wiki/AJAX
    - http://www.w3schools.com/ajax/default.asp

    Comment by Cameron Manderson — August 9, 2006 @ 12:08 pm

  2. Another good reference I came across today:
    http://developer.mozilla.org/en/docs/AJAX

    Comment by Richard Lee — August 10, 2006 @ 1:09 pm

  3. Cam, I also read older versions of Mozilla lock-up if the server returns anything other than XML, so they suggest adding overrideMimeType method call in the Mozilla/Safari code
    xmlHttpReq.overrideMimeType('text/xml');

    Comment by Richard Lee — August 11, 2006 @ 11:21 am

  4. Nice pickup :-)

    Comment by Cameron Manderson — August 14, 2006 @ 9:42 am

  5. Does anybody know, how to use send fucntion with POST?
    XMLHttpRequest.open(”POST”, url, true);
    XMLHttpRequest.send(something….)
    How can I specify the “something…”?
    thanx

    Comment by ivan kubica — August 23, 2006 @ 12:47 am

  6. When you make a request with POST you will need to specify the “something…” like the contents of a GET request:

    myvar=myVal&whichever=whatever

    This will need to be correctly encoded the same you do for GET requests.

    Have a look at a reference I found for you:
    http://www.yourhtmlsource.com/javascript/ajax.html#buildingarequest

    Comment by Cameron Manderson — August 23, 2006 @ 9:31 am

  7. Ensure if you are using a server side response that is built be a script that you specify the expiry headers manually. IE reportedly has a bug. From PHP the example would be as follows:

    header( “Expires: Mon, 26 Jul 1997 05:00:00 GMT” ); // disable IE caching
    header( “Last-Modified: ” . gmdate( “D, d M Y H:i:s” ) . ” GMT” );
    header( “Cache-Control: no-cache, must-revalidate” );
    header( “Pragma: no-cache” );

    Comment by Cameron Manderson — August 23, 2006 @ 9:32 am

RSS feed for comments on this post. TrackBack URI

Leave a comment