mastering ajax

Upload: miriyamsatyanarayana

Post on 14-Apr-2018

244 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/27/2019 Mastering Ajax

    1/43

    Mastering Ajax, Part 1: Introduction to AjaxUnderstanding Ajax, a productive approach to building Web sites, and how it works

    Level: Introductory

    Brett McLaughlin([email protected]), Author and Editor, O'Reilly Media Inc.06 Dec 2005Ajax, which consists of HTML, JavaScript technology, DHTML, and DOM, is an outstanding approach that helps you transform clunky Web interfaces into

    interactive Ajax applications. The author, an Ajax expert, demonstrates how these technologies work together -- from an overview to a detailed look -- to

    make extremely efficient Web development an easy reality. He also unveils the central concepts of Ajax, including the XMLHttpRequest object.

    Five years ago, if you didn't know XML, you were the ugly duckling whom nobody talked to. Eighteen months ago, Ruby came into the limelight and

    programmers who didn't know what was going on with Ruby weren't welcome at the water cooler. Today, if you want to get into the latest technology rage,

    Ajax is where it's at.However, Ajax is far more thanjusta fad; it's a powerful approach to building Web sites and it's not nearly as hard to learn as an entire new language.

    Before I dig into what Ajax is, though, let's spend just a few moments understanding what Ajax does. When you write an application today, you have two

    basic choices:

    Desktop applications

    Web applications

    These are both familiar; desktop applications usually come on a CD (or sometimes are downloaded from a Web site) and install completely on your

    computer. They might use the Internet to download updates, but the code that runs these applications resides on your desktop. Web applications -- and

    there's no surprise here -- run on a Web server somewhere and you access the application with your Web browser.More important than where the code for these applications runs, though, is how the applications behave and how you interact with them. Desktop

    applications are usually pretty fast (they're running on your computer; you're not waiting on an Internet connection), have great user interfaces (usuallyinteracting with your operating system), and are incredibly dynamic. You can click, point, type, pull up menus and sub-menus, and cruise around, with

    almost no waiting around.

    On the other hand, Web applications are usually up-to-the-second current and they provide services you could never get on your desktop (think about

    Amazon.com and eBay). However, with the power of the Web comes waiting -- waiting for a server to respond, waiting for a screen to refresh, waiting for a

    request to come back and generate a new page.Obviously this is a bit of an oversimplification, but you get the basic idea. As you might already be suspecting, Ajax attempts to bridge the gap between thefunctionality and interactivity of a desktop application and the always-updated Web application. You can use dynamic user interfaces and fancier controls like

    you'd find on a desktop application, but it's available to you on a Web application.

    So what are you waiting for? Start looking at Ajax and how to turn your clunky Web interfaces into responsive Ajax applications.

    Old technology, new tricks

    When it comes to Ajax, the reality is that it involves a lot of technologies -- to get beyond the basics, you need to drill down into several differenttechnologies (which is why I'll spend the first several articles in this series breaking apart each one of them). The good news is that you might already know

    a decent bit about many of these technologies -- better yet, most of these individual technologies are easy to learn -- certainly not as difficult as an entire

    programming language like Java or Ruby.

    Here are the basic technologies involved in Ajax applications:

    HTML is used to build Web forms and identify fields for use in the rest of your application.

    JavaScript code is the core code running Ajax applications and it helps facilitate communication with server applications.

    DHTML, or Dynamic HTML, helps you update your forms dynamically. You'll use div, span, and other dynamic HTML elements to mark up your HTML.

    DOM, the Document Object Model, will be used (through JavaScript code) to work with both the structure of your HTML and (in some cases) XML

    returned from the server.

    Let's break these down and get a better idea of what each does. I'll delve into each of these more in future articles; for now focus on becoming familiar with

    these components and technologies. The more familiar you are with this code, the easier it will be to move from casual knowledge about these technologies

    to mastering each (and really blowing the doors off of your Web application development).

    The XMLHttpRequest objectThe first object you want to understand is probably the one that's newest to you; it's called XMLHttpRequest. This is a JavaScript object and is created as

    simply as shown in Listing 1.

    Listing 1. Create a new XMLHttpRequest object

    Ajax defined

    By the way, Ajax is shorthand for Asynchronous JavaScript

    and XML (and DHTML, and so on). The phrase was coined

    by Jesse James Garrett of Adaptive Path (see theResourcessection) and is, according to Jesse, notmeant to

    be an acronym.

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#author%23authorhttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#author%23authormailto:[email protected]?subject=Introduction%20to%20Ajax&[email protected]://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code1%23code1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#author%23authormailto:[email protected]?subject=Introduction%20to%20Ajax&[email protected]://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code1%23code1
  • 7/27/2019 Mastering Ajax

    2/43

    var xmlHttp = new XMLHttpRequest();

    I'll talk more about this object in the next article, but for now realize that this is the object that handles all your server communication. Before you go

    forward, stop and think about that -- it's theJavaScripttechnology through the XMLHttpRequest object that talks to the server. That's not the normal

    application flow and it's where Ajax gets much of its magic.

    In a normal Web application, users fill out form fields and click a Submitbutton. Then, the entire form is sent to the server, the server passes on processing

    to a script (usually PHP or Java or maybe a CGI process or something similar), and when the script is done, it sends back a completely new page. That page

    might be HTML with a new form with some data filled in or it might be a confirmation or perhaps a page with certain options selected based on data entered

    in the original form. Of course, while the script or program on the server is processing and returning a new form, users have to wait. Their screen will goblank and then be redrawn as data comes back from the server. This is where low interactivity comes into play -- users don't get instant feedback and they

    certainly don't feel like they're working on a desktop application.

    Ajax essentially puts JavaScript technology and the XMLHttpRequest object between your Web form and the server. When users fill out forms, that data is

    sent to some JavaScript code and notdirectly to the server. Instead, the JavaScript code grabs the form data and sends a request to the server. While this is

    happening, the form on the users screen doesn't flash, blink, disappear, or stall. In other words, the JavaScript code sends the request behind the scenes;the user doesn't even realize that the request is being made. Even better, the request is sent asynchronously, which means that your JavaScript code (and

    the user) doesn't wait around on the server to respond. So users can continue entering data, scrolling around, and using the application.

    Then, the server sends data back to your JavaScript code (still standing in for the Web form) which decides what to do with that data. It can update form

    fields on the fly, giving that immediate feeling to your application -- users are getting new data without their form being submitted or refreshed. TheJavaScript code could even get the data, perform some calculations, and send another request, all without user intervention! This is the power of

    XMLHttpRequest. It can talk back and forth with a server all it wants, without the user ever knowing about what's really going on. The result is a dynamic,

    responsive, highly-interactive experience like a desktop application, but with all the power of the Internet behind it.

    Adding in some JavaScriptOnce you get a handle on XMLHttpRequest, the rest of your JavaScript code turns out to be pretty mundane. In fact, you'll use JavaScript code for just a few

    basic tasks:

    Get form data: JavaScript code makes it simple to pull data out of your HTML form and send it to the server. Change values on the form: It's also simple to update a form, from setting field values to replacing images on the fly.

    Parse HTML and XML: You'll use JavaScript code to manipulate the DOM (see the next section) and to work with the structure of your HTML form

    and any XML data that the server returns.

    For those first two items, you want to be very familiar with the getElementById() method as shown in Listing 2.

    Listing 2. Grab and set field values with JavaScript code

    // Get the value of the "phone" field and stuff it in a variable called phone

    var phone = document.getElementById("phone").value;

    // Set some values on a form using an array called responsedocument.getElementById("order").value = response[0];document.getElementById("address").value = response[1];

    There's nothing particularly remarkable here and that's good! You should start to realize that there's nothing tremendously complicated about this. Once you

    master XMLHttpRequest, much of the rest of your Ajax application will be simple JavaScript code like that shown in Listing 2, mixed in with a bit of clever

    HTML. Then, every once in a while, there's a little DOM work...so let's look at that.

    Finishing off with the DOMLast but not least, there's the DOM, the Document Object Model. For some of you, hearing about the DOM is going to be a little intimidating -- it's not often

    used by HTML designers and is even somewhat unusual for JavaScript coders unless you're really into some high-end programming tasks. Where you will

    find the DOM in use a lot is in heavy-duty Java and C/C++ programs; in fact, that's probably where the DOM got a bit of its reputation for being difficult orhard to learn.

    Fortunately, using the DOM in JavaScript technology is easy, and is mostly intuitive. At this point, I'd normally show you how to use the DOM or at least giveyou a few code examples, but even that would be misleading. You see, you can get pretty far into Ajax without having to mess with the DOM and that's the

    path I'm going to show you. I'll come back to the DOM in a future article, but for now, just know that it's out there. When you start to send XML back and

    forth between your JavaScript code and the server and really change the HTML form, you'll dig back into DOM. For now, it's easy to get some effective Ajax

    going without it, so put this on the back-burner for now.

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#dom%23domhttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code2%23code2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code2%23code2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#dom%23domhttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code2%23code2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code2%23code2
  • 7/27/2019 Mastering Ajax

    3/43

    Getting a Request objectWith a basic overview under your belt, you're ready to look at a few specifics. Since XMLHttpRequest is central to Ajax applications -- and probably new to

    many of you -- I'll start there. As you saw in Listing 1, it should be pretty easy to create this object and use it, right? Wait a minute.Remember those pesky browser wars from a few years back and how nothing worked the same across browsers? Well, believe it or not, those wars are still

    going on albeit on a much smaller scale. And, surprise: XMLHttpRequest is one of the victims of this war. So you'll need to do a few different things to get an

    XMLHttpRequest object going. I'll take your through it step by step.

    Working with Microsoft browsersMicrosoft's browser, Internet Explorer, uses the MSXML parser for handling XML (you can find out more about MSXML in Resources). So when you write Ajax

    applications that need to work on Internet Explorer, you need to create the object in a particular way.However, it's not that easy. MSXML actually has two different versions floating around depending on the version of JavaScript technology installed in

    Internet Explorer, so you've got to write code that handles both cases. Look at Listing 3 for the code that you need to create an XMLHttpRequest on Microsoft

    browsers.

    Listing 3. Create an XMLHttpRequest object on Microsoft browsers

    var xmlHttp = false;try {xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (e) {try {xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

    } catch (e2) {xmlHttp = false;

    }}

    All of this won't make exact sense yet, but that's OK. You'll dig into JavaScript programming, error handling, conditional compilation, and more before this

    series is finished. For now, you want to get two core lines into your head:xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

    and

    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");.

    In a nutshell, this code tries to create the object using one version of MSXML; if that fails, it then creates the object using the other version. Nice, huh? If

    neither of these work, the xmlHttp variable is set to false, to tell your code know that something hasn't worked. If that's the case, you've probably got a non-

    Microsoft browser and need to use different code to do the job.

    Dealing with Mozilla and non-Microsoft browsersIf Internet Explorer isn't your browser of choice or you write code for non-Microsoft browsers, then you need different code. In fact, this is the really simple

    line of code you saw back in Listing 1:var xmlHttp = new XMLHttpRequest object;.

    This much simpler line creates an XMLHttpRequest object in Mozilla, Firefox, Safari, Opera, and pretty much every other non-Microsoft browser that supports

    Ajax in any form or fashion.

    Putting it togetherThe key is to support allbrowsers. Who wants to write an application that works just on Internet Explorer or an application that works just on non-Microsoft

    browsers? Worse yet, do you want to write your application twice? Of course not! So your code combines support for both Internet Explorerand non-

    Microsoft browsers. Listing 4 shows the code to do just that.

    Listing 4. Create an XMLHttpRequest object the multi-browser way

    /* Create a new XMLHttpRequest object to talk to the Web server */var xmlHttp = false;/*@cc_on @*//*@if (@_jscript_version >= 5)try {xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (e) {try {xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

    } catch (e2) {xmlHttp = false;

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code3%23code3http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code3%23code3http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code1%23code1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code4%23code4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code4%23code4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code4%23code4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code1%23code1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code3%23code3http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code1%23code1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code4%23code4
  • 7/27/2019 Mastering Ajax

    4/43

    }}@end @*/

    if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {xmlHttp = new XMLHttpRequest();}

    For now, ignore the commenting and weird tags like @cc_on; those are special JavaScript compiler commands that you'll explore in depth in my next article,

    which will focus exclusively on XMLHttpRequest. The core of this code breaks down into three steps:

    1. Create a variable, xmlHttp, to reference the XMLHttpRequest object that you will create.

    2. Try and create the object in Microsoft browsers:

    o Try and create the object using the Msxml2.XMLHTTP object.

    o If that fails, try and create the object using the Microsoft.XMLHTTP object.

    3. IfxmlHttp still isn't set up, create the object in a non-Microsoft way.

    At the end of this process, xmlHttp should reference a valid XMLHttpRequest object, no matter what browser your users run.

    A word on securityWhat about security? Today's browsers offer users the ability to crank their security levels up, to turn off JavaScript technology, and disable any number of

    options in their browser. In these cases, your code probably won't work under any circumstances. For these situations, you'll have to handle problems

    gracefully -- that's at least one article in itself, one I will tackle later ( it's going to be a long series, isn't it? Don't worry; you'll master all of this before you're

    through). For now, you're writing robust, but not perfect, code, which is great for getting a handle on Ajax. You'll come back to the finer details.

    Request/Response in an Ajax worldSo you now understand Ajax and have a basic idea about the XMLHttpRequest object and how to create it. If you've read closely, you even realize that it's the

    JavaScript technology that talks to any Web application on the server rather than your HTML form being submitted to that application directly.

    What's the missing piece? How to actually use XMLHttpRequest. Since this is critical code that you'll use in some form in everyAjax application you write, take

    a quick tour through what a basic request/response model with Ajax looks like.

    Making a requestYou have your shiny new XMLHttpRequest object; now take it for a spin. First, you need a JavaScript method that your Web page can call (like when a user

    types in text or selects an option from a menu). Then, you'll follow the same basic outline in almost all of your Ajax applications:1. Get whatever data you need from the Web form.

    2. Build the URL to connect to.3. Open a connection to the server.

    4. Set up a function for the server to run when it's done.

    5. Send the request.

    Listing 5 is a sample of an Ajax method that does these very things, in this order:

    Listing 5. Make a request with Ajax

    function callServer() {// Get the city and state from the web formvar city = document.getElementById("city").value;

    var state = document.getElementById("state").value;// Only go on if there are values for both fieldsif ((city == null) || (city == "")) return;if ((state == null) || (state == "")) return;

    // Build the URL to connect tovar url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);

    // Open a connection to the serverxmlHttp.open("GET", url, true);

    // Setup a function for the server to run when it's done

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code5%23code5http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code5%23code5
  • 7/27/2019 Mastering Ajax

    5/43

    xmlHttp.onreadystatechange = updatePage;

    // Send the requestxmlHttp.send(null);

    }

    A lot of this is self-explanatory. The first bit of the code uses basic JavaScript code to grab the values of a few form fields. Then the code sets up a PHP script

    as the destination to connect to. Notice how the URL of the script is specified and then the city and state (from the form) are appended to this using simple

    GET parameters.

    Next, a connection is opened; here's the first place you see XMLHttpRequest in action again. The method of connection is indicated (GET), as well as the URL

    to connect to. The final parameter, when set to true, requests an asynchronous connection (thus making this Ajax). If you used false, the code would wait

    around on the server when the request was made and not continue until a response was received. By setting this to true, your users can still use the form

    (and even call other JavaScript methods) while the server is processing this request in the background.The onreadystatechange property ofxmlHttp (remember, that's your instance of the XMLHttpRequest object) allows you to tell the server what to do when it

    does finish running (which could be in five minutes or five hours). Since the code isn't going to wait around for the server, you'll need to let the server know

    what to do so you can respond to it. In this case, a specific method -- called updatePage() -- will be triggered when the server is finished processing your

    request.Finally, send() is called with a value ofnull. Since you've added the data to send to the server (the city and state) in the request URL, you don't need to

    send anything in the request. So this fires off your request and the server can do what you asked it to do.

    If you don't get anything else out of this, notice how straightforward and simple this is! Other than getting the asynchronous nature of Ajax into your head,

    this is relatively simple stuff. You'll appreciate how it frees you up to concentrate on cool applications and interfaces rather than complicated HTTP

    request/response code.

    The code in Listing 5 is about as easy as it gets. The data is simple text and can be included as part of the request URL. GET sends the request rather than

    the more complicated POST. There's no XML or content headers to add, no data to send in the body of the request -- this is Ajax Utopia, in other words.Have no fear; things will become more complicated as this series progresses. You'll learn how to send POST requests, how to set request headers and

    content types, how to encode XML in your message, how to add security to your request -- the list is pretty long! Don't worry about the hard stuff for now;

    get your head around the basics, and you'll soon build up a whole arsenal of Ajax tools.

    Handling the responseNow you need to actually deal with the server's response. You really only need to know two things at this point:

    Don't do anything until the xmlHttp.readyState property is equal to 4.

    The server will stuff it's response into the xmlHttp.responseText property.

    The first of these -- ready states -- is going to take up the bulk of the next article; you'll learn more about the stages of an HTTP request than you ever

    wanted to know. For now, if you simply check for a certain value (4), things will work (and you'll have something to look forward to in the next article). The

    second item -- using the xmlHttp.responseText property to get the server's response -- is easy. Listing 6 shows an example of a method that the server can

    call based on the values sent in Listing 5.

    Listing 6. Handle the server's response

    function updatePage() {if (xmlHttp.readyState == 4) {var response = xmlHttp.responseText;document.getElementById("zipCode").value = response;

    }}

    Again, this code isn't so difficult or complicated. It waits for the server to call it with the right ready state and then uses the value that the server returns (in

    this case, the ZIP code for the user-entered city and state) to set the value of another form field. The result is that the zipCode field suddenly appears with

    the ZIP code -- but the user never had to click a button!. That's the desktop application feel I talked about earlier. Responsiveness, a dynamic feel, and

    more, all with a little Ajax code.Observant readers might notice that the zipCode field is a normal text field. Once the server returns the ZIP code and the updatePage() method sets the value

    of that field with the city/state ZIP code, users can override the value. That's intentional for two reasons: To keep things in the example simple and to show

    you that sometimes you wantusers to be able to override what a server says. Keep both in mind; they're important in good user-interface design.

    Hooking in the Web formSo what's left? Actually, not much. You have a JavaScript method that grabs information that the user put into a form, sends it to the server, provides

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code5%23code5http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code5%23code5http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code7%23code7http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code5%23code5http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code6%23code6http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code5%23code5http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#code7%23code7
  • 7/27/2019 Mastering Ajax

    6/43

    another JavaScript method to listen for and handle a response, and even sets the value of a field when that response comes back. All that's really left is tocallthat first JavaScript method and start the whole process. You could obviously add a button to your HTML form, but that's pretty 2001, don't you think?

    Take advantage of JavaScript technology like in Listing 7.

    Listing 7. Kick off an Ajax process

    City:

    State:

    Zip Code:

    If this feels like yet one more piece of fairly routine code, then you're right -- it is! When a user puts in a new value for either the city or state field, the

    callServer() method fires off and the Ajax fun begins. Starting to feel like you've got a handle on things? Good; that's the idea!

    In conclusionAt this point, you're probably not ready to go out and write your first Ajax application -- at least, not unless you're willing to do some real digging in theResources section. However, you can start to get the basic idea of how these applications work and a basic understanding of the XMLHttpRequest object. In

    the articles to come, you'll learn to master this object, how to handle JavaScript-to-server communication, how to work with HTML forms, and even get a

    handle on the DOM.For now, though, spend some time thinking about just how powerful Ajax applications can be. Imagine a Web form that responds to you not just when you

    click a button, but when you type into a field, when you select an option from a combo box...even when you drag your mouse around the screen. Think

    about exactly what asynchronous means; think about JavaScript code running and not waiting on the server to respond to its requests. What sorts of

    problems can you run into? What areas do you watch out for? And how will the design of your forms change to account for this new approach in

    programming?

    If you spend some real time with these issues, you'll be better served than just having some code you can cut-and-paste and throw into an application thatyou really don't understand. In the next article, you'll put these ideas into practice and I'll give you the details on the code you need to really make

    applications like this work. So, until then, enjoy the possibilities of Ajax.

    Mastering Ajax, Part 2:Make asynchronous requests with JavaScript and AjaxUse XMLHttpRequest for Web requests

    Level: Intermediate

    Brett McLaughlin ([email protected]), Author and Editor, O'Reilly Media Inc.

    17 Jan 2006

    Most Web applications use a request/response model that gets an entire HTML page from the server. The result is a back-and-forth that usually involves

    clicking a button, waiting for the server, clicking another button, and then waiting some more. With Ajax and the XMLHttpRequest object, you can use a

    request/response model that never leaves users waiting for a server to respond. In this article, Brett McLaughlin shows you how to create XMLHttpRequestinstances in a cross-browser way, construct and send requests, and respond to the server.

    In the last article of this series (see Resources for links), you were introduced to the Ajax applications and looked at some of the basic concepts that

    drive Ajax applications. At the center of this was a lot of technology that you probably already know about: JavaScript, HTML and XHTML, a bit of dynamic

    HTML, and even some DOM (the Document Object Model). In this article, I will zoom in from that 10,000-foot view and focus on specific Ajax details.

    In this article, you'll begin with the most fundamental and basic of all Ajax-related objects and programming approaches: The XMLHttpRequest object. Thisobject is really the only common thread across all Ajax applications and -- as you might expect -- you will want to understand it thoroughly to take your

    programming to the limits of what's possible. In fact, you'll find out that sometimes, to use XMLHttpRequest properly, you explicitly won'tuse XMLHttpRequest.

    What in the world is that all about?

    Web 2.0 at a glanceFirst, take this last bit of overview before you dive into code -- make sure you're crystal clear on this idea of the Web 2.0. When you hear the term Web 2.0,you should first ask, "What's Web 1.0?" Although you'll rarely hear Web 1.0, it is meant to refer to the traditional Web where you have a very distinct

    request and response model. For example, go to Amazon.com and click a button or enter a search term. A request is made to a server and then a response

    comes back to your browser. That request has a lot more than just a list of books and titles, though; it's actually another complete HTML page. As a result,

    you probably get some flashing or flickering as your Web browser's screen is redrawn with this new HTML page. In fact, you can clearly see the request andresponse, delineated by each new page you see.

    The Web 2.0 dispenses with this very visible back-and-forth (to a large degree). As an example, visit a site like Google Maps or Flickr (links to both of these

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#author%23authormailto:[email protected]?subject=Make%20asynchronous%20requests%20with%20JavaScript%20and%20Ajax&[email protected]://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro1.html#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#author%23authormailto:[email protected]?subject=Make%20asynchronous%20requests%20with%20JavaScript%20and%20Ajax&[email protected]://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#resources%23resources
  • 7/27/2019 Mastering Ajax

    7/43

    Web 2.0, Ajax-powered sites are in Resources). On Google Maps, for example, you can drag the map around and zoom in and zoom out with very littleredrawing. Of course, requests and responses do go on here, but all behind the scenes. As a user, the experience is much more pleasant and feels a lot like

    a desktop application. This new feel and paradigm is what you see when someone refers to Web 2.0.

    What you should care about then is how to make these new interactions possible. Obviously, you've still got to make requests and field responses, but it's

    the redrawing of the HTML for every request/response interaction that gives the perception of a slow, clunky Web interface. So clearly you need an approach

    that allows you to make requests and receive responses that include onlythe data you need, rather than an entire HTML page as well. The only time youwant to get a whole new HTML page is when ... well ... when you want the user to see a new page.But most interactions add details or change body text or overlay data on the existing pages. In all of these cases, Ajax and a Web 2.0 approach make it

    possible to send and receive data withoutupdating an entire HTML page. And to any frequent Web surfer, this ability will make your application feel faster,

    more responsive, and bring them back over and over again.

    Introducing XMLHttpRequest

    To make all this flash and wonder actually happen, you need to become intimately familiar with a JavaScript object called XMLHttpRequest. This little object --which has actually been around in several browsers for quite a while -- is the key to Web 2.0, Ajax, and pretty much everything else you learn about in this

    column for the next several months. To give you a really quick overview, these are just a fewof the methods and properties you'll use on this object:

    open(): Sets up a new request to a server.

    send(): Sends a request to a server.

    abort(): Bails out of the current request.

    readyState: Provides the current HTML ready state.

    responseText: The text that the server sends back to respond to a request.

    Don't worry if you don't understand all of this (or anyof this for that matter) -- you'll learn about each method and property in the next several articles.

    What you shouldget out of this, though, is a good idea of what to do with XMLHttpRequest. Notice that each of these methods and properties relate to

    sending a request and dealing with a response. In fact, if you saw every method and property ofXMLHttpRequest, they would allrelate to that very simplerequest/response model. So clearly, you won't learn about an amazing new GUI object or some sort of super-secret approach to creating user interaction;

    you will work with simple requests and simple responses. It might not sound exciting, but careful use of this one object can totally change your applications.

    The simplicity of newFirst, you need to create a new variable and assign it to an instance of the XMLHttpRequest object. That's pretty simple in JavaScript; you just use the new

    keyword with the object name, like you see in Listing 1.

    Listing 1. Create a new XMLHttpRequest object

    var request = new XMLHttpRequest();

    That's not too hard, is it? Remember, JavaScript doesn't require typing on its variable, so you don't need anything like you see in Listing 2 (which might be

    how you'd create this object in Java).

    Listing 2. Java pseudo-code for creating XMLHttpRequest

    XMLHttpRequest request = new XMLHttpRequest();

    So you create a variable in JavaScript with var, give it a name (like "request"), and then assign it to a new instance ofXMLHttpRequest. At that point, you're

    ready to use the object in your functions.

    Error handlingIn real life, things can go wrong and this code doesn't provide any error-handling. A slightly better approach is to create this object and have it gracefully fail

    if something goes wrong. For example, many older browsers (believe it or not, people are still using old versions of Netscape Navigator) don't support

    XMLHttpRequest and you need to let those users know that something has gone wrong. Listing 3 shows how you might create this object so if something fails,

    it throws out a JavaScript alert.

    Listing 3. Create XMLHttpRequest with some error-handling abilities

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code1%23code1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code1%23code1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code2%23code2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code3%23code3
  • 7/27/2019 Mastering Ajax

    8/43

    var request = false;try {

    request = new XMLHttpRequest();} catch (failed) {request = false;

    }

    if (!request)alert("Error initializing XMLHttpRequest!");

    Make sure you understand each of these steps:

    1. Create a new variable called request and assign it a false value. You'll use false as a condition that means the XMLHttpRequest object hasn't been

    created yet.

    2. Add in a try/catch block:

    1. Try and create the XMLHttpRequest object.

    2. If that fails (catch (failed)), ensure that request is still set to false.

    3. Check and see ifrequest is still false (if things are going okay, it won't be).

    4. If there was a problem (and request is false), use a JavaScript alert to tell users there was a problem.

    This is pretty simple; it takes longer to read and write about than it does to actually understand for most JavaScript and Web developers. Now you've got an

    error-proof piece of code that creates an XMLHttpRequest object and even lets you know if something went wrong.

    Dealing with MicrosoftThis all looks pretty good ... at least until you try this code in Internet Explorer. If you do, you're going to get something that looks an awful lot like Figure 1.

    Figure 1. Internet Explorer reporting an error

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#fig1%23fig1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#fig1%23fig1
  • 7/27/2019 Mastering Ajax

    9/43

    Clearly, something isn't working; Internet Explorer is hardly an out-of-date browserand about 70 percent of the world uses Internet Explorer. In other words, you won't

    do well in the Web world if you don't support Microsoft and Internet Explorer! So, you

    need a different approach to deal with Microsoft's browsers.

    It turns out that Microsoft supports Ajax, but calls its version ofXMLHttpRequest something different. In fact, it calls it severaldifferent things. If you're using

    a newer version of Internet Explorer, you need to use an object called Msxml2.XMLHTTP; some older versions of Internet Explorer use Microsoft.XMLHTTP. You

    need to support these two object types (without losing the support you already have for non-Microsoft browsers). Check out Listing 4 which adds Microsoftsupport to the code you've already seen.

    Listing 4. Add support for Microsoft browsers

    var request = false;try {request = new XMLHttpRequest();

    } catch (trymicrosoft) {try {request = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (othermicrosoft) {try {request = new ActiveXObject("Microsoft.XMLHTTP");

    } catch (failed) {

    request = false;}

    }}

    if (!request)alert("Error initializing XMLHttpRequest!");

    It's easy to get lost in the curly braces, so I'll walk you through this one step at a time:

    1. Create a new variable called request and assign it a false value. Use false as a condition that means the XMLHttpRequest object isn't created yet.

    2. Add in a try/catch block:1. Try and create the XMLHttpRequest object.

    2. If that fails (catch (trymicrosoft)):

    1. Try and create a Microsoft-compatible object using the newer versions of Microsoft (Msxml2.XMLHTTP).

    2. If that fails (catch (othermicrosoft)), try and create a Microsoft-compatible object using the older versions of Microsoft

    (Microsoft.XMLHTTP).

    3. If that fails (catch (failed)), ensure that request is still set to false.

    3. Check and see ifrequest is still false (if things are okay, it won't be).

    4. If there was a problem (and request is false), use a JavaScript alert to tell users there was a problem.

    Make these changes to your code and try things out in Internet Explorer again; you should see the form you created (without an error message). In mycase, that results in something like Figure 2.

    Figure 2. Internet Explorer working normally

    Microsoft playing nice?Much has been written about Ajax and Microsoft's increasing

    interest and presence in that space. In fact, Microsoft's newest

    version of Internet Explorer -- version 7.0, set to come out late in

    2006 -- is supposed to move to supporting XMLHttpRequest directly,allowing you to use the new keyword instead of all the

    Msxml2.XMLHTTP creation code. Don't get too excited, though; you'll

    still need to support old browsers, so that cross-browser code isn't

    going away anytime soon.

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code4%23code4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#fig2%23fig2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code4%23code4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#fig2%23fig2
  • 7/27/2019 Mastering Ajax

    10/43

    Static versus dynamicTake a look back at Listings 1, 3, and 4 and notice that all of this code is nested directly within script tags. When JavaScript is coded like that and not put

    within a method or function body, it's called static JavaScript. This means that the code is run sometime before the page is displayed to the user. (It's not

    100 percent clear from the specificationpreciselywhen this code runs and browsers do things differently; still, you're guaranteed that the code is run before

    users can interact with your page.) That's usually how most Ajax programmers create the XMLHttpRequest object.

    That said, you certainly can put this code into a method as shown in Listing 5.

    Listing 5. Move XMLHttpRequest creation code into a method

    var request;

    function createRequest() {try {request = new XMLHttpRequest();

    } catch (trymicrosoft) {try {request = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (othermicrosoft) {

    try {request = new ActiveXObject("Microsoft.XMLHTTP");

    } catch (failed) {request = false;

    }}

    }

    if (!request)alert("Error initializing XMLHttpRequest!");

    }

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code1%23code1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code3%23code3http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code4%23code4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code5%23code5http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code1%23code1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code3%23code3http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code4%23code4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code5%23code5
  • 7/27/2019 Mastering Ajax

    11/43

    With code setup like this, you'll need to call this method before you do any Ajax work. So you might have something like Listing 6.

    Listing 6. Use an XMLHttpRequest creation method

    var request;

    function createRequest() {try {request = new XMLHttpRequest();

    } catch (trymicrosoft) {try {request = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (othermicrosoft) {try {request = new ActiveXObject("Microsoft.XMLHTTP");

    } catch (failed) {request = false;

    }}

    }

    if (!request)alert("Error initializing XMLHttpRequest!");

    }

    function getCustomerInfo() {createRequest();// Do something with the request variable

    }

    The only concern with this code -- and the reason most Ajax programmers don't use this approach -- is that it delays error notification. Suppose you have a

    complex form with 10 or 15 fields, selection boxes, and the like, and you fire off some Ajax code when the user enters text in field 14 (way down the form).

    At that point, getCustomerInfo() runs, tries to create an XMLHttpRequest object, and (for this example) fails. Then an alert is spit out to the user, telling them

    (in so many words) that they can't use this application. But the user has already spent time entering data in the form! That's pretty annoying and annoyance

    is not something that typically entices users back to your site.In the case where you use static JavaScript, the user is going to get an error as soon as they hit your page. Is that also annoying? Perhaps; it could make

    users mad that your Web application won't run on their browser. However, it's certainly better than spitting out that same error after they've spent 10

    minutes entering information. For that reason alone, I encourage you to set up your code statically and let users know early on about possible problems.

    Sending requests with XMLHttpRequestOnce you have your request object, you can begin the request/response cycle. Remember, XMLHttpRequest's only purpose is to allow you to make requests

    and receive responses. Everything else -- changing the user interface, swapping out images, even interpreting the data that the server sends back -- is the

    job of JavaScript, CSS, or other code in your pages. With XMLHttpRequest ready for use, now you can make a request to a server.

    Welcome to the sandboxAjax has a sandbox security model. As a result, your Ajax code (and specifically, the XMLHttpRequest object) can only make requests to the same domain on

    which it's running. You'll learn lots more about security and Ajax in an upcoming article, but for now realize that code running on your local machine can only

    make requests to server-side scripts on your local machine. If you have Ajax code running on www.breakneckpizza.com, it must make requests to scriptsthat run on www.breakneckpizza.com.

    Setting the server URLThe first thing you need to determine is the URL of the server to connect to. This isn't specific to Ajax -- obviously you should know how to construct a URL

    by now -- but is still essential to making a connection. In most applications, you'll construct this URL from some set of static data combined with data from

    the form your users work with. For example, Listing 7 shows some JavaScript that grabs the value of the phone number field and then constructs a URL

    using that data.

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code6%23code6http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code7%23code7http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code6%23code6http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code7%23code7
  • 7/27/2019 Mastering Ajax

    12/43

    Listing 7. Build a request URL

    var request = false;try {request = new XMLHttpRequest();

    } catch (trymicrosoft) {try {request = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (othermicrosoft) {try {request = new ActiveXObject("Microsoft.XMLHTTP");

    } catch (failed) {request = false;

    }

    }}

    if (!request)alert("Error initializing XMLHttpRequest!");

    function getCustomerInfo() { var phone = document.getElementById("phone").value;

    var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);}

    Nothing here should trip you up. First, the code creates a new variable named phone and assigns the value of the form field with an ID of "phone." Listing 8shows the XHTML for this particular form in which you can see the phone field and its id attribute.

    Listing 8. The Break Neck Pizza form

    Enter your phone number:

    Your order will be delivered to:

    Type your order in here:

    Also notice that when users enter their phone number or change the number, it fires off the getCustomerInfo() method shown in Listing 8. That method then

    grabs the number and uses it to construct a URL string stored in the url variable. Remember: Since Ajax code is sandboxed and can only connect to the

    same domain, you really shouldn't need a domain name in your URL. In this example, the script name is /cgi-local/lookupCustomer.php. Finally, the phone

    number is appended to this script as a GET parameter: "phone=" + escape(phone).If you've never seen the escape() method before, it's used to escape any characters that can't be sent as clear text correctly. For example, any spaces in the

    phone number are converted to %20 characters, making it possible to pass the characters along in the URL.

    You can add as many parameters as you need. For example, if you wanted to add another parameter, just append it onto the URL and separate parameters

    with the ampersand (&) character [the first parameter is separated from the script name with a question mark (?)].

    Opening the request

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code8%23code8http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code8%23code8http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code8%23code8http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code8%23code8http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code8%23code8
  • 7/27/2019 Mastering Ajax

    13/43

    With a URL to connect to, you can configure the request. You'll accomplish this usingthe open() method on your XMLHttpRequest object. This method takes as many as five

    parameters:

    request-type: The type of request to send. Typical values are GET or POST, but you can also send HEAD requests.

    url: The URL to connect to.

    asynch: True if you want the request to be asynchronous and false if it should be a synchronous request. This parameter is optional and defaults to

    true.

    username: If authentication is required, you can specify the username here. This is an optional parameter and has no default value.

    password: If authentication is required, you can specify the password here. This is an optional parameter and has no default value.

    Typically, you'll use the first three of these. In fact, even when you want an asynchronous request, you should specify "true" as the third parameter. That'sthe default setting, but it's a nice bit of self-documentation to always indicate if the request is asynchronous or not.

    Put it all together and you usually end up with a line that looks a lot like Listing 9.

    Listing 9. Open the request

    function getCustomerInfo() {var phone = document.getElementById("phone").value;var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);

    request.open("GET", url, true);}

    Once you have the URL figured out, then this is pretty trivial. For most requests, using GET is sufficient (you'll see the situations in which you might want to

    use POST in future articles); that, along with the URL, is all you need to use open().

    A teaser on asynchronicityIn a later article in this series, I'll spend significant time on writing and using asynchronous code, but you should get an idea of why that last parameter in

    open() is so important. In a normal request/response model -- think Web 1.0 here -- the client (your browser or the code running on your local machine)

    makes a request to the server. That request is synchronous; in other words, the client waits for a response from the server. While the client is waiting, you

    usually get at least one of several forms of notification that you're waiting:

    An hourglass (especially on Windows).

    A spinning beachball (usually on Mac machines).

    The application essentially freezes and sometimes the cursor changes.

    This is what makes Web applications in particular feel clunky or slow -- the lack of real interactivity. When you push a button, your application essentially

    becomes unusable until the request you just triggered is responded to. If you've made a request that requires extensive server processing, that wait might

    be significant (at least for today's multi-processor, DSL, no-waiting world).An asynchronous request though, does notwait for the server to respond. You send a request and then your application continues on. Users can still enter

    data in a Web form, click other buttons, even leave the form. There's no spinning beachball or whirling hourglass and no big application freeze. The server

    quietly responds to the request and when it's finished, it let's the original requestor know that it's done (in ways you'll see in just a moment). The end result

    is an application that doesn'tfeel clunky or slow, but instead is responsive, interactive, and feels faster. This is just one component of Web 2.0, but it's a

    very important one. All the slick GUI components and Web design paradigms can't overcome a slow, synchronous request/response model.

    Sending the requestOnce you configure the request with open(), you're ready to send the request. Fortunately, the method for sending a request is named more properly than

    open(); it's simply called send().send() takes only a single parameter, the content to send. But before you think too much on that, recall that you are already sending data through the URL

    itself:

    var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);

    Although you can send data using send(), you can also send data through the URL itself. In fact, in GET requests (which will constitute as much as 80 percent

    of your typical Ajax usage), it's much easier to send data in the URL. When you start to send secure information or XML, then you want to look at sending

    content through send() (I'll discuss both secure data and XML messaging in a later article in this series). When you don't need to pass data along through

    send(), then just pass null as the argument to this method. So, to send a request in the example you've seen throughout this article, that's exactly what is

    needed (see Listing 10).

    Does open() open?Internet developers disagree about what exactly the open()

    method does. What it does notdo is actually open a request. If

    you were to monitor the network and data transfer between your

    XHTML/Ajax page and the script that it connects to, you wouldn'tsee any traffic when the open() method is called. It's unclear why

    the name was chosen, but it clearly wasn't a great choice.

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code9%23code9
  • 7/27/2019 Mastering Ajax

    14/43

    Listing 10. Send the request

    function getCustomerInfo() {var phone = document.getElementById("phone").value;var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);request.open("GET", url, true);

    request.send(null);}

    Specifying a callback methodAt this point, you've done very little that feels new, revolutionary, or asynchronous. Granted, that little keyword "true" in the open() method sets up an

    asynchronous request. But other than that, this code resembles programming with Java servlets and JSPs, PHP, or Perl. So what's the big secret to Ajax and

    Web 2.0? The secret revolves around a simple property ofXMLHttpRequest called onreadystatechange.

    First, be sure you understand the process that you created in this code (review Listing 10 if you need to). A request is set up and then made. Additionally,

    because this is a synchronous request, the JavaScript method (getCustomerInfo() in the example) will not wait for the server. So the code will continue; inthis case, that means that the method will exit and control will return to the form. Users can keep entering information and the application isn't going to wait

    on the server.

    This creates an interesting question, though: What happens when the server has finished processing the request? The answer, at least as the code stands

    right now, is nothing! Obviously, that's not good, so the server needs to have some type of instruction on what to do when it's finished processing the

    request sent to it by XMLHttpRequest.

    This is where that onreadystatechange property comes into play. This property allows you to specify a callback method. A callback allows the server to (can

    you guess?) call backinto your Web page's code. It gives a degree of control to the server, as well; when the server finishes a request, it looks in the

    XMLHttpRequest object and specifically at the onreadystatechange property. Whatever method is specified by that property is then invoked. It's a callback

    because the server initiates calling back into the Web page -- regardless of what is going in the Web page itself. For example, it might call this method while

    the user is sitting in her chair, not touching the keyboard; however, it might also call the method while the user is typing, moving the mouse, scrolling,

    clicking a button ... it doesn't matter what the user is doing.

    This is actually where the asynchronicity comes into play: The user operates the form on one level while on another level, the server answers a request and

    then fires off the callback method indicated by the onreadystatechange property. So you need to specify that method in your code as shown in Listing 11.

    Listing 11. Set a callback method

    function getCustomerInfo() {var phone = document.getElementById("phone").value;var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);request.open("GET", url, true);

    request.onreadystatechange = updatePage;request.send(null);

    }

    Pay close attention to where in the code this property is set -- it's before send() is called. You must set this property before the request is sent, so the server

    can look up the property when it finishes answering a request. All that's left now is to code the updatePage() which is the focus of the last section in this

    article.

    Handling server responsesYou made your request, your user is happily working in the Web form (while the server handles the request), and now the server finishes up handling the

    request. The server looks at the onreadystatechange property and figures out what method to call. Once that occurs, you can think of your application as any

    other app, asynchronous or not. In other words, you don't have to take any special action writing methods that respond to the server; just change the form,

    Referencing a function in JavaScript

    JavaScript is a loosely typed language and you can reference just

    about anything as a variable. So if you declare a function called

    updatePage(), JavaScript also treats that function name as a

    variable. In other words, you can reference the function in your

    code as a variable named updatePage.

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code10%23code10http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code10%23code10http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code10%23code10http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code11%23code11
  • 7/27/2019 Mastering Ajax

    15/43

    take the user to another URL, or do whatever else you need to in response to the server. In this section, we'll focus on responding to the server and thentaking a typical action -- changing on the fly part of the form the user sees.

    Callbacks and AjaxYou've already seen how to let the server know what to do when it's finished: Set the onreadystatechange property of the XMLHttpRequest object to the name

    of the function to run. Then, when the server has processed the request, it will automatically call that function. You also don't need to worry about any

    parameters to that method. You'll start with a simple method like in Listing 12.

    Listing 12. Code the callback method

    var request = false;try {request = new XMLHttpRequest();

    } catch (trymicrosoft) {try {request = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (othermicrosoft) {try {request = new ActiveXObject("Microsoft.XMLHTTP");

    } catch (failed) {request = false;

    }}

    }

    if (!request)alert("Error initializing XMLHttpRequest!");

    function getCustomerInfo() {var phone = document.getElementById("phone").value;var url = "/cgi-local/lookupCustomer.php?phone=" + escape(phone);request.open("GET", url, true);request.onreadystatechange = updatePage;request.send(null);

    }

    function updatePage() {alert("Server is done!");

    }

    This just spits out a handy alert, to tell you when the server is done. Try this code in your own page, save the page, and then pull it up in a browser (if you

    want the XHTML from this example, refer back to Listing 8). When you enter in a phone number and leave the field, you should see the alert pop up (seeFigure 3); but click OK and it pops up again ... and again.

    Figure 3. Ajax code popping up an alert

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#fig3%23fig3http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code12%23code12http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code8%23code8http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#fig3%23fig3
  • 7/27/2019 Mastering Ajax

    16/43

    Depending on your browser, you'll get two, three, or even four alerts before the form stops popping up alerts. So what's going on? It turns out that youhaven't taken into account the HTTP ready state, an important component of the request/response cycle.

    HTTP ready statesEarlier, I said that the server, once finished with a request, looks up what method to call in the onreadystatechange property ofXMLHttpRequest. That's true,

    but it's not the whole truth. In fact, it calls that method every time the HTTP ready state changes. So what does that mean? Well, you've got to understand

    HTTP ready states first.An HTTP ready state indicates the state or status of a request. It's used to figure out if a request has been started, if it's being answered, or if the

    request/response model has completed. It's also helpful in determining whether it's safe to read whatever response text or data that a server might have

    supplied. You need to know about five ready states in your Ajax applications:

    0: The request is uninitialized (before you've called open()).

    1: The request is set up, but hasn't been sent (before you've called send()).

    2: The request was sent and is being processed (you can usually get content headers from the response at this point).

    3: The request is being processed; often some partial data is available from the response, but the server hasn't finished with its response.

    4: The response is complete; you can get the server's response and use it.

    As with almost all cross-browser issues, these ready states are used somewhat inconsistently. You might expect to always see the ready state move from 0

    to 1 to 2 to 3 to 4, but in practice, that's rarely the case. Some browsers never report 0 or 1 and jump straight to 2, then 3, and then 4. Other browsers

    report all states. Still others will report ready state 1 multiple times. As you saw in the last section, the server called updatePage() several times and each

    invocation resulted in an alert box popping up -- probably not what you intended!

    For Ajax programming, the only state you need to deal with directly is ready state 4, indicating that a server's response is complete and it's safe to check

    the response data and use it. To account for this, the first line in your callback method should be as shown in Listing 13.

    Listing 13. Check the ready state

    function updatePage() { if (request.readyState == 4)

    alert("Server is done!");}

    This change checks to ensure that the server really is finished with the process. Try running this version of the Ajax code and you should only get the alert

    message one time, which is as it should be.

    HTTP status codes

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code13%23code13http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code13%23code13
  • 7/27/2019 Mastering Ajax

    17/43

    Despite the apparent success of the code in Listing 13, there's still a problem -- what if the server responds to your request and finishes processing, butreports an error? Remember, your server-side code should care if it's being called by Ajax, a JSP, a regular HTML form, or any other type of code; it only has

    the traditional Web-specific methods of reporting information. And in the Web world, HTTP codes can deal with the various things that might happen in a

    request.

    For example, you've certainly entered a request for a URL, typed the URL incorrectly, and received a 404 error code to indicate a page is missing. This is just

    one of many status codes that HTTP requests can receive as a status (see Resourcesfor a link to the complete list of status codes). 403 and 401, bothindicating secure or forbidden data being accessed, are also common. In each of these cases, these are codes that result from a completed response. Inother words, the server fulfilled the request (meaning the HTTP ready state is 4), but is probably not returning the data expected by the client.

    In addition to the ready state then, you also need to check the HTTP status. You're looking for a status code of 200 which simply means okay. With a ready

    state of 4 and a status code of 200, you're ready to process the server's data and that data should be what you asked for (and not an error or other

    problematic piece of information). Add another status check to your callback method as shown in Listing 14.

    Listing 14. Check the HTTP status code

    function updatePage() {if (request.readyState == 4)

    if (request.status == 200)alert("Server is done!");

    }

    To add more robust error handling -- with minimal complication -- you might add a check or two for other status codes; check out the modified version of

    updatePage() in Listing 15.

    Listing 15. Add some light error checking

    function updatePage() {

    if (request.readyState == 4)if (request.status == 200)alert("Server is done!");

    else if (request.status == 404)alert("Request URL does not exist");

    elsealert("Error: status code is " + request.status);

    }

    Now change the URL in your getCustomerInfo() to a non-existent URL and see what happens. You should see an alert that tells you the URL you asked for

    doesn't exist -- perfect! This is hardly going to handle every error condition, but it's a simple change that covers 80 percent of the problems that can occur ina typical Web application.

    Reading the response textNow that you made sure the request was completely processed (through the ready state) and the server gave you a normal, okay response (through the

    status code), you can finally deal with the data sent back by the server. This is conveniently stored in the responseText property of the XMLHttpRequest object.

    Details about what the text in responseText looks like, in terms of format or length, is left intentionally vague. This allows the server to set this text to

    virtually anything. For instance, one script might return comma-separated values, another pipe-separated values (the pipe is the | character), and another

    may return one long string of text. It's all up to the server.

    In the case of the example used in this article, the server returns a customer's last order and then their address, separated by the pipe symbol. The order

    and address are both then used to set values of elements on the form; Listing 16 shows the code that updates the display.

    Listing 16. Deal with the server's response

    function updatePage() {if (request.readyState == 4) {if (request.status == 200) {

    var response = request.responseText.split("|");document.getElementById("order").value = response[0];document.getElementById("address").innerHTML =response[1].replace(/\n/g, "

    ");} elsealert("status is " + request.status);

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code13%23code13http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code14%23code14http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code15%23code15http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code16%23code16http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code13%23code13http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code14%23code14http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code15%23code15http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro2/#code16%23code16
  • 7/27/2019 Mastering Ajax

    18/43

    }}

    First, the responseText is pulled and split on the pipe symbol using the JavaScript split() method. The resulting array of values is dropped into response. The

    first value -- the customer's last order -- is accessed in the array as response[0] and is set as the value of the field with an ID of "order." The second value inthe array, at response[1], is the customer's address and it takes a little more processing. Since the lines in the address are separated by normal line

    separators (the "\n" character), the code needs to replace these with XHTML-style line separators,
    s. That's accomplished through the use of the

    replace() function along with a regular expression. Finally, the modified text is set as the inner HTML of a div in the HTML form. The result is that the form

    suddenly is updated with the customer's information, as you can see in Figure 4.

    Figure 4. The Break Neck form after it retrieves customer data

    Before I wrap up, another important property ofXMLHttpRequest is called responseXML. That property contains (can you guess?) an XML response in the event

    that the server chooses to respond with XML. Dealing with an XML response is quite different than dealing with plain text and involves parsing, the

    Document Object Model (DOM), and several other considerations. You'll learn more about XML in a future article. Still, because responseXML commonly comes

    up in discussions surrounding responseText, it's worth mentioning here. For many simple Ajax applications, responseText is all you need, but you'll soon learn

    about dealing with XML through Ajax applications as well.

    In conclusionYou might be a little tired ofXMLHttpRequest -- I rarely read an entire article about a single object, especially one that is this simple. However, you will use

    this object over and over again in each page and application that you write that uses Ajax. Truth be told, there's quite a bit still to be said about

    XMLHttpRequest. In coming articles, you'll learn to use POST in addition to GET in your requests, set and read content headers in your request as well as the

    response from the server; you'll understand how to encode your requests and even handle XML in your request/response model.

    Quite a bit further down the line, you'll also see some of the popular Ajax toolkits that are available. These toolkits actually abstract away most of the details

    discussed in this article and make Ajax programming easier. You might even wonder why you have to code all this low-level detail when toolkits are soreadily available. The answer is, it's awfully hard to figure out what goes wrong in your application if you don't understand whatis going on in your

    application.

    So don't ignore these details or speed through them; when your handy-dandy toolkit creates an error, you won't be stuck scratching your head and sending

    an email to support. With an understanding of how to use XMLHttpRequest directly, you'll find it easy to debug and fix even the strangest problems. Toolkits

  • 7/27/2019 Mastering Ajax

    19/43

    are fine unless you count on them to take care of all your problems.So get comfortable with XMLHttpRequest. In fact, if you have Ajax code running that uses a toolkit, try to rewrite it using just the XMLHttpRequest object and

    its properties and methods. It will be a great exercise and probably help you understand what's going on a lot better.

    In the next article, you'll dig even deeper into this object, exploring some of its tricker properties (like responseXML), as well as how to use POST requests and

    send data in several different formats. So start coding and check back here in about a month.

    Mastering Ajax, Part 3:Advanced requests and responses in AjaxGain a complete understanding of HTTP status codes, ready states, and the XMLHttpRequest object

    Level: IntroductoryBrett McLaughlin([email protected]), Author and Editor, O'Reilly Media Inc.

    14 Feb 2006

    For many Web developers, making simple requests and receiving simple responses is all they'll ever need, but for developers who want to master Ajax, a

    complete understanding of HTTP status codes, ready states, and the XMLHttpRequest object is required. In this article, Brett McLaughlin will show you the

    different status codes and demonstrate how browsers handle each and he will showcase the lesser-used HTTP requests that you can make with Ajax.

    In the last article in this series, I provided a solid introduction to the XMLHttpRequest object, the centerpiece of an Ajax application that handles requeststo a server-side application or script, and also deals with return data from that server-side component. Every Ajax application uses the XMLHttpRequest

    object, so you'll want to be intimately familiar with it to make your Ajax applications perform and perform well.

    In this article, I move beyond the basics in the last article and concentrate on more detail about three key parts of this request object:

    The HTTP ready state

    The HTTP status code

    The types of requests that you can make

    Each of these is generally considered part of the plumbing of a request; as a result, little detail is recorded about these subjects. However, you will need to

    be fluent in ready states, status codes, and requests if you want to do more than just dabble in Ajax programming. When something goes wrong in your

    application -- and things always go wrong -- understanding ready states, how to make a HEAD request, or what a 400 status code means can make the

    difference between five minutes of debugging and five hours of frustration and confusion.I'll look at HTTP ready states first.

    Digging deeper into HTTP ready statesYou should remember from the last article that the XMLHttpRequest object has a property called readyState. This property ensures that a server hascompleted a request and typically, a callback function uses the data from the server to update a Web form or page. Listing 1shows a simple example of this

    (also in the last article in this series -- see Resources).

    Listing 1. Deal with a server's response in a callback function

    function updatePage() { if (request.readyState == 4) {

    if (request.status == 200) {var response = request.responseText.split("|");document.getElementById("order").value = response[0];document.getElementById("address").innerHTML =response[1].replace(/\n/g, "
    ");

    } elsealert("status is " + request.status);

    }}

    This is definitely the most common (and most simple) usage of ready states. As you might guess from the number "4," though, there are several other

    ready states (you also saw this list in the last article -- see Resources):

    0: The request is uninitialized (before you've called open()).

    XMLHttpRequest or XMLHttp: A rose by any other name

    Microsoft and Internet Explorer use an object called XMLHttp instead of

    the XMLHttpRequest object used by Mozilla, Opera, Safari, and most non-

    Microsoft browsers. For the sake of simplicity, I refer to both of theseobject types simply as XMLHttpRequest. This matches the common practice

    you'll find all over the Web and is also in line with Microsoft's intentions of

    using XMLHttpRequest as the name of their request object in Internet

    Explorer 7.0. (For more on this, look at Part 2 again.)

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#author%23authorhttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#author%23authormailto:[email protected]?subject=Advanced%20requests%20and%20responses%20in%20Ajax&[email protected]://www.ibm.com/developerworks/web/library/wa-ajaxintro2/http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing1%23listing1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing1%23listing1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#resources%23resourceshttp://www.ibm.com/developerworks/web/library/wa-ajaxintro2/http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#author%23authormailto:[email protected]?subject=Advanced%20requests%20and%20responses%20in%20Ajax&[email protected]://www.ibm.com/developerworks/web/library/wa-ajaxintro2/http://www.ibm.com/developerworks/web/library/wa-ajaxintro2/http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing1%23listing1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#resources%23resourceshttp://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#resources%23resources
  • 7/27/2019 Mastering Ajax

    20/43

    1: The request is set up, but not sent (before you've called send()).

    2: The request was sent and is in process (you can usually get content headers from the response at this point).

    3: The request is in process; often some partial data is available from the response, but the server isn't finished with its response.

    4: The response is complete; you can get the server's response and use it.

    If you want to go beyond the basics of Ajax programming, you need to know not only these states, but when they occur and how you can use them. First

    and foremost, you need to learn at what state of a request you encounter each ready state. Unfortunately, this is fairly non-intuitive and also involves a few

    special cases.

    Ready states in hidingThe first ready state, signified by the readyState property 0 (readyState == 0), represents an uninitialized request. As soon as you call open() on your request

    object, this property is set to 1. Because you almost always call open() as soon as you initialize your request, it's rare to see readyState == 0. Furthermore,

    the uninitialized ready state is pretty useless in practical applications.Still, in the interest of being complete, check out Listing 2 which shows how to get the ready state when it's set to 0.

    Listing 2. Get a 0 ready state

    function getSalesData() {// Create a request objectcreateRequest();

    alert("Ready state is: " + request.readyState);

    // Setup (initialize) the requestvar url = "/boards/servlet/UpdateBoardSales";request.open("GET", url, true);request.onreadystatechange = updatePage;request.send(null);

    }

    In this simple example, getSalesData() is the function that your Web page calls to start a request (like when a button is clicked). Note that you've got to

    check the ready state before open() is called. Figure 1 shows the result of running this application.

    Figure 1. A ready state of 0

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing2%23listing2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#fig1%23fig1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing2%23listing2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#fig1%23fig1
  • 7/27/2019 Mastering Ajax

    21/43

    Obviously, this doesn't do you much good; there are very few times whenyou'll need to make sure that open()hasn'tbeen called. The only use for this

    ready state in almost-real-world Ajax programming is if you make multiple

    requests using the same XMLHttpRequest object across multiple functions. In

    that (rather unusual) situation, you might want to ensure that a request

    object is in an uninitialized state (readyState == 0) before making a newrequests. This essentially ensures that another function isn't using the object

    at the same time.

    Viewing an in-progress request's ready stateAside from the 0 ready state, your request object should go through each of the other ready states in a typical request and response, and finally end up with

    a ready state of 4. That's when the if (request.readyState == 4) line of code you see in most callback functions comes in; it ensures the server is done and

    it's safe to update a Web page or take action based on data from the server.

    It is a trivial task to actually see this process as it takes place. Instead of only running code in your callback if the ready state is 4, just output the ready

    state every time that your callback is called. For an example of code that does this, check out Listing 3.

    Listing 3. Check the ready state

    function updatePage() {// Output the current ready statealert("updatePage() called with ready state of " + request.readyState);

    }

    If you're not sure how to get this running, you'll need to create a function to call from your Web page and have it send a request to a server-side component

    (just such a function was shown in Listing 2and throughout the examples in both the first and second articles in this series). Make sure that when you setup your request, you set the callback function to updatePage(); to do this, set the onreadystatechange property of your request object to updatePage().

    This code is a great illustration of exactly what onreadystatechange means -- every time the request's ready state changes, updatePage() is called and you see

    an alert. Figure 2 shows a sample of this function being called, in this case with a ready state of 1.

    Figure 2. A ready state of 1

    Try this code yourself. Put it into your Web page and then activate your event handler (click a button, tab out of a field, or use whatever method you set upto trigger a request). Your callback function will run several times -- each time the ready state of the request changes -- and you'll see an alert for each

    ready state. This is the best way to follow a request through each of its stages.

    Browser inconsistenciesOnce you've a basic understanding of this process, try to access your Web page from several different browsers. You should notice some inconsistencies in

    When 0 is equal to 4In the use case where multiple JavaScript functions use the same request

    object, checking for a ready state of 0 to ensure that the request object

    isn't in use can still turn out to be problematic. Since readyState == 4

    indicates a completed request, you'll often find request objects that are

    notbeing used with their ready state still set at 4 -- the data from the

    server was used, but nothing has occurred since then to reset the ready

    state. There is a function that resets a request object called abort(), but

    it's not really intended for this use. If you have to use multiple functions, it

    might be better to create and use a request object for each function rather

    than to share the object across multiple functions.

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing3%23listing3http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing2%23listing2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing2%23listing2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#fig2%23fig2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing3%23listing3http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing2%23listing2http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#fig2%23fig2
  • 7/27/2019 Mastering Ajax

    22/43

    how these ready states are handled. For example, in Firefox 1.5, you see the following ready states:

    1

    2

    3

    4

    This shouldn't be a surprise since each stage of a request is represented here. However, if you access the same application using Safari, you should see -- or

    rather, not see -- something interesting. Here are the states you see on Safari 2.0.1:

    2

    3

    4

    Safari actually leaves out the first ready state and there's no sensible explanation as to why; it's simply the way Safari works. It also illustrates an importantpoint: While it's a good idea to ensure the ready state of a request is 4 before using data from the server, writing code that depends on each interim ready

    state is a sure way to get different results on different browsers.

    For example, when using Opera 8.5, things are even worse with displayed ready states: 3

    4

    Last but not least, Internet Explorer responds with the following states:

    1

    2

    3

    4

    If you have trouble with a request, this is the very first place to look for problems. Add an alert to show you the request's ready state so you can ensure thatthings are operating normally. Better yet, test on both Internet Explorer and Firefox -- you'll get all four ready states and be able to check each stage of therequest.

    Next I look at the response side.

    Response data under the microscopeOnce you understand the various ready states that occur during a request, you're ready to look at another important piece of the XMLHttpRequest object --

    the responseText property. Remember from the last article that this is the property used to get data from the server. Once a server has finished processing a

    request, it places any data that is needed to respond to the request back in the responseText of the request. Then, your callback function can use that data,

    as seen in Listing 1 and Listing 4.

    Listing 4. Use the response from the server

    function updatePage() {if (request.readyState == 4) {var newTotal = request.responseText;var totalSoldEl = document.getElementById("total-sold");var netProfitEl = document.getElementById("net-profit");replaceText(totalSoldEl, newTotal);

    /* Figure out the new net profit */var boardCostEl = document.getElementById("board-cost");var boardCost = getText(boardCostEl);var manCostEl = document.getElementById("man-cost");var manCost = getText(manCostEl);var profitPerBoard = boardCost - manCost;var netProfit = profitPerBoard * newTotal;

    /* Update the net profit on the sales form */netProfit = Math.round(netProfit * 100) / 100;replaceText(netProfitEl, netProfit);

    }

    Listing 1 is fairly simple; Listing 4 is a little more complicated, but to begin, both check the ready state and then grab the value (or values) in the

    responseText property.

    http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing1%23listing1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing4%23listing4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing1%23listing1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing4%23listing4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing1%23listing1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing4%23listing4http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing1%23listing1http://www-128.ibm.com/developerworks/web/library/wa-ajaxintro3/#listing4%23listing4
  • 7/27/2019 Mastering Ajax

    23/43

    Viewing the response text during a requestLike the ready state, the value of the responseText property changes throughout the request's life cycle. To see this in action, use code like that shown in

    Listing 5 to test the response text of a request, as well as its ready state.

    Listing 5. Test the responseText property

    function updatePage() {// Output the curr