Mastering Ajax, Part 1: Introduction to Ajax

Understanding Ajax, a productive approach to building Web sites, and how it works By: http://www.ibm.com/developerworks/views/web/libraryview.jsp?search_by=Mastering+Ajax Level: Introductory Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc. 06 Dec 2005 Ajax, 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 than just a 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:
y y

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 (usually interacting 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, and 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 the functionality 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 different technologies (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. 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 the Resources section) and is, according to Jesse, not meant to be an acronym. Here are the basic technologies involved in Ajax applications:
y y y y

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 object The 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 <script language="javascript" type="text/javascript"> var xmlHttp = new XMLHttpRequest(); </script> 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 the JavaScript technology 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 Submit button. 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 go blank 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 not directly 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. The JavaScript 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 JavaScript Once 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:
y y y

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 response document.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 DOM Last 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 or hard 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 give you 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.

Getting a Request object With 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 browsers Microsoft'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 browsers If 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 together The key is to support all browsers. 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 Explorer and 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; } } @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. If xmlHttp 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 security What 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 world So 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 every Ajax application you write, take a quick tour through what a basic request/response model with Ajax looks like. Making a request You have your shiny new XMLHttpRequest object; now take it for a spin. First, you need a JavaScript method that you¶re 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. 2. 3. 4. 5. Get whatever data you need from the Web form. Build the URL to connect to. Open a connection to the server. Set up a function for the server to run when it's done. 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 // Get the city and state from the web form function callServer() { var city = document.getElementById("city").value; var state = document.getElementById("state").value; // Only go on if there are values for both fields if ((city == null) || (city == "")) return;

if ((state == null) || (state == "")) return; // Build the URL to connect to var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state); // Open a connection to the server xmlHttp.open("GET", url, true); // Setup a function for the server to run when it's done xmlHttp.onreadystatechange = updatePage; // Send the request xmlHttp.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 of xmlHttp (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 of null. 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 fire 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 response Now you need to actually deal with the server's response. You really only need to know two things at this point:
y y

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 want users 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 form So 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 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 to call that 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 <form> <p>City: <input type="text" name="city" id="city" size="25" onChange="callServer();" onChange="callServer();" /></p> /></p> <p>State: <input type="text" name="state" id="state" size="25" <p>Zip Code: <input type="text" name="zipCode" id="zipCode" size="5" /></p> </form> 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 conclusion At 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 the Resources 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 that you 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 Ajax Use XMLHttpRequest for Web requests Level: Intermediate Brett McLaughlin (brett@newInstance.com), 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 XMLHttpRequest instances 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. This object 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't use XMLHttpRequest. What in the world is that all about? Web 2.0 at a glance First, 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 and response, 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 Web 2.0, Ajaxpowered sites are in Resources). On Google Maps, for example, you can drag the map around and zoom in and zoom out with very little redrawing. 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 only the data you need, rather than an entire HTML page as well. The only time you want 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 without updating 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 few of the methods and properties you'll use on this object:
y y y y y

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 any of this for that matter) -- you'll learn about each method and property in the next several articles. What you should get 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 of XMLHttpRequest, they would all relate to that very simple request/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 new First, 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 <script language="javascript" type="text/javascript"> var request = new XMLHttpRequest(); </script> 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 of XMLHttpRequest. At that point, you're ready to use the object in your functions. Error handling In 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 <script language="javascript" type="text/javascript"> var request = false; try { request = new XMLHttpRequest(); } catch (failed) { request = false; } if (!request) alert("Error initializing XMLHttpRequest!"); </script> 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 if request 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 Microsoft This 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

Clearly, something isn't working; Internet Microsoft playing nice? Explorer is hardly an out-of-date browser and Much has been written about Ajax about 70 percent of the world uses Internet and Microsoft's increasing interest Explorer. In other words, you won't do well in and presence in that space. In fact, the Web world if you don't support Microsoft Microsoft's newest version of and Internet Explorer! So, you need a different Internet Explorer -- version 7.0, set approach to deal with Microsoft's browsers. to come out late in 2006 -- is It turns out that Microsoft supports Ajax, but supposed to move to supporting calls its version of XMLHttpRequest something XMLHttpRequest directly, allowing you different. In fact, it calls it several different to use the new keyword instead of all things. If you're using a newer version of the Msxml2.XMLHTTP creation code. Internet Explorer, you need to use an object Don't get too excited, though; you'll called Msxml2.XMLHTTP; some older versions of still need to support old browsers, so Internet Explorer use Microsoft.XMLHTTP. You that cross-browser code isn't going need to support these two object types (without away anytime soon. losing the support you already have for nonMicrosoft browsers). Check out Listing 4 which adds Microsoft support to the code you've already seen. Listing 4. Add support for Microsoft browsers <script language="javascript" type="text/javascript"> 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!"); </script> 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 Microsoftcompatible 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 if request 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 my case, that results in something like Figure 2. Figure 2. Internet Explorer working normally

Static versus dynamic Take 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 specification precisely when 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 <script language="javascript" type="text/javascript"> 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!"); } </script> 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 <script language="javascript" type="text/javascript"> 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 } </script>

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 XMLHttpRequest Once 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 sandbox Ajax 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 serverside scripts on your local machine. If you have Ajax code running on www.breakneckpizza.com, it must make requests to scripts that run on www.breakneckpizza.com. Setting the server URL The 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. Listing 7. Build a request URL <script language="javascript" type="text/javascript"> 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); } </script> 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 8 shows 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 <body> <p><img src="breakneck-logo_4c.gif" alt="Break Neck Pizza" /></p> <form action="POST"> <p>Enter your phone number: <input type="text" size="14" name="phone" id="phone" onChange="getCustomerInfo();" /> </p> <p>Your order will be delivered to:</p> <div id="address"></div> <p>Type your order in here:</p> <p><textarea name="order" rows="6" cols="50" id="order"></textarea></p> <p><input type="submit" value="Order Pizza" id="submit" /></p> </form> </body> 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 With a URL to connect to, you can configure the Does open() open? request. You'll accomplish this using the open() Internet developers disagree about method on your XMLHttpRequest object. This what exactly the open() method method takes as many as five parameters: does. What it does not do is actually
y

y y

y y

open a request. If you were to request-type: The type of request to monitor the network and data send. Typical values are GET or POST, transfer between your XHTML/Ajax but you can also send HEAD requests. page and the script that it connects url: The URL to connect to. to, you wouldn't see any traffic when asynch: True if you want the request to the open() method is called. It's be asynchronous and false if it should be unclear why the name was chosen, a synchronous request. This parameter is but it clearly wasn't a great choice. 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's the 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 asynchronicity In 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:
y y y

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 not wait 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't feel 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 request Once 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). 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 method At 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 of XMLHttpRequest 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 an asynchronous request, the JavaScript method (getCustomerInfo() in the example) will not wait for the server. So the code will continue; in this 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 Referencing a function in JavaScript comes into play. This property allows you to JavaScript is a loosely typed specify a callback method. A callback allows the language and you can reference just server to (can you guess?) call back into your about anything as a variable. So if Web page's code. It gives a degree of control to you declare a function called the server, as well; when the server finishes a updatePage(), JavaScript also treats request, it looks in the XMLHttpRequest object that function name as a variable. In and specifically at the onreadystatechange other words, you can reference the property. Whatever method is specified by that function in your code as a variable property is then invoked. It's a callback because named updatePage. 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 responses You 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, 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 then taking a typical action -- changing on the fly part of the form the user sees. Callbacks and Ajax You'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 <script language="javascript" type="text/javascript"> 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!"); } </script> 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 (see Figure 3); but click OK and it pops up again ... and again. Figure 3. Ajax code popping up an alert

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 you haven't taken into account the HTTP ready state, an important component of the request/response cycle. HTTP ready states Earlier, I said that the server, once finished with a request, looks up what method to call in the onreadystatechange property of XMLHttpRequest. 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:
y y y y

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

y

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 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, but reports 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 Resources for a link to the complete list of status codes). 403 and 401, both indicating secure or forbidden data being accessed, are also common. In each of these cases, these are codes that result from a completed response. In other 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"); else alert("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 in a typical Web application. Reading the response text Now 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, " "); } else alert("status is " + request.status); } } 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 in the 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, <br />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 of XMLHttpRequest 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.

Back to top In conclusion You might be a little tired of XMLHttpRequest -- 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 so readily available. The answer is, it's awfully hard to figure out what goes wrong in your application if you don't understand what is 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 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 Ajax Gain a complete understanding of HTTP status codes, ready states, and the XMLHttpRequest object Level: Introductory Document options Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc. Print this 14 Feb 2006 page For many Web developers, making simple requests and E-mail this receiving simple responses is all they'll ever need, but page for developers who want to master Ajax, a complete Document understanding of HTTP status codes, ready states, and options the XMLHttpRequest object is required. In this article, requiring Brett McLaughlin will show you the different status codes JavaScript are and demonstrate how browsers handle each and he will not displayed showcase the lesser-used HTTP requests that you can Discuss make with Ajax. Sample code In the last article in this series, I provided a solid introduction to the XMLHttpRequest object, the Rate this page centerpiece of an Ajax application that handles requests to a server-side application or script, and also deals with Help us return data from that server-side component. Every Ajax improve this application uses the XMLHttpRequest object, so you'll content 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:
y y y

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. XMLHttpRequest or XMLHttp: A rose Digging deeper into HTTP ready states by any other name You should remember from the last MicrosoftΠand Internet Explorer article that the XMLHttpRequest object use an object called XMLHttp instead has a property called readyState. This of the XMLHttpRequest object used property ensures that a server has by Mozilla, Opera, Safari, and most completed a request and typically, a non-Microsoft browsers. For the callback function uses the data from sake of simplicity, I refer to both of the server to update a Web form or these object types simply as page. Listing 1 shows a simple XMLHttpRequest. This matches the example of this (also in the last article common practice you'll find all over in this series -- see Resources). the Web and is also in line with Microsoft's intentions of using Listing 1. Deal with a server's XMLHttpRequest as the name of their response in a callback function request object in Internet Explorer 7.0. (For more on this, look at Part 2 again.)

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, "<br />"); } else alert("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):
y y y y y

0: The request is uninitialized (before you've called open()). 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 hiding The 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 object createRequest(); alert("Ready state is: " + request.readyState); // Setup (initialize) the request var 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

Obviously, this doesn't do you much When 0 is equal to 4 good; there are very few times when In the use case where multiple you'll need to make sure that open() JavaScript functions use the same hasn't been called. The only use for request object, checking for a ready this ready state in almost-real-world state of 0 to ensure that the request Ajax programming is if you make object isn't in use can still turn out multiple requests using the same to be problematic. Since readyState XMLHttpRequest object across multiple == 4 indicates a completed request, functions. In that (rather unusual) you'll often find request objects that situation, you might want to ensure are not being used with their ready that a request object is in an state still set at 4 -- the data from uninitialized state (readyState == 0) the server was used, but nothing before making a new requests. This has occurred since then to reset the essentially ensures that another ready state. There is a function that function isn't using the object at the resets a request object called same time. abort(), but it's not really intended Viewing an in-progress request's ready state for this use. If you have to use Aside from the 0 ready state, your multiple functions, it might be request object should go through each better to create and use a request of the other ready states in a typical object for each function rather than request and response, and finally end to share the object across multiple up with a ready state of 4. That's functions. 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 state alert("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 2 and throughout the examples in both the first and second articles in this series). Make sure that when you set up 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 up to 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 inconsistencies Once you've a basic understanding of this process, try to access your Web

page from several different browsers. You should notice some inconsistencies in how these ready states are handled. For example, in Firefox 1.5, you see the following ready states:
y y y y

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:
y y y

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 important point: 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:
y y

3 4

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

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 that things 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 the request. Next I look at the response side. Response data under the microscope Once 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. Viewing the response text during a request Like 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 current ready state alert("updatePage() called with ready state of " + request.readyState + " and a response text of '" + request.responseText + "'"); } Now open your Web application in a browser and activate your request. To get the most out of this code, use either Firefox or Internet Explorer since those two browsers both report all possible ready states during a request. At a ready state of 2, for example, the responseText property is undefined (see Figure 3); you'd see an error if the JavaScript console was open as well.

Figure 3. Response text with a ready state of 2

At ready state 3 though, the server has placed a value in the responseText property, at least in this example (see Figure 4). Figure 4. Response text with a ready state of 3

You'll find that your responses in ready state 3 vary from script to script, server to server, and browser to browser. Still, this is remains incredibly helpful in debugging your application. Getting safe data All of the documentation and specifications insist that it's only when the ready state is 4 that data is safe to use. Trust me, you'll rarely find a case where the data cannot be obtained from the responseText property when the ready state

is 3. However, to rely on that in your application is a bad idea -- the one time you write code that depends on complete data at ready state 3 is almost guaranteed to be the time the data is incomplete. A better idea is to provide some feedback to the user that when the ready state is 3, a response is forthcoming. While using a function like alert() is obviously a bad idea -- using Ajax and then blocking the user with an alert dialog box is pretty counterintuitive -- you could update a field on your form or page as the ready state changes. For example, try to set the width of a progress indicator to 25 percent for a ready state of 1, 50 percent for a ready state of 2, 75 percent for a ready state of 3, and 100 percent (complete) when the ready state is 4. Of course, as you've seen, this approach is clever but browser-dependent. On Opera, you'll never get those first two ready states and Safari drops the first one (1). For that reason, I'll leave code like this as an exercise rather than include it in this article. Time to take a look at status codes. A closer look at HTTP status codes With ready states and the server's response in your bag of Ajax programming techniques, you're ready to add another level of sophistication to your Ajax applications -- working with HTTP status codes. These codes are nothing new to Ajax. They've been around on the Web for as long as there has been a Web. You've probably already seen several of these through your Web browser:
y y y

401: Unauthorized 403: Forbidden 404: Not Found

You can find more (for a complete list, see Resources). To add another layer of control and responsiveness (and particularly more robust error-handling) to your Ajax applications, then you need to check the status codes in a request and respond appropriately. 200: Everything is OK In many Ajax applications, you'll see a callback function that checks for a ready state and then goes on to work with the data from the server response, as in Listing 6. Listing 6. Callback function that ignores the status code function updatePage() { if (request.readyState == 4) { var response = request.responseText.split("|"); document.getElementById("order").value = response[0]; document.getElementById("address").innerHTML = response[1].replace(/\n/g, "<br />"); } } This turns out to be a short-sighted and error-prone approach to Ajax

programming. If a script requires authentication and your request does not provide valid credentials, the server will return an error code like 403 or 401. However, the ready state will be set to 4 since the server answered the request (even if the answer wasn't what you wanted or expected for your request). As a result, the user is not going to get valid data and might even get a nasty error when your JavaScript tries to use non-existent server data. It takes minimal effort to ensure that the server not only finished with a request, but returned an "Everything is OK" status code. That code is "200" and is reported through the status property of the XMLHttpRequest object. To make sure that not only did the server finish with a request but that it also reported an OK status, add an additional check in your callback function as shown in Listing 7. Listing 7. Check for a valid status code 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, "<br />"); } else alert("status is " + request.status); } } With the addition of a few lines of code, you can be certain that if something does go wrong, your users will get a (questionably) helpful error message rather than seeing a page of garbled data with no explanation. Redirection and rerouting Before I talk in depth about errors, it's worth talking about something you probably don't have to worry about when you're using Ajax -- redirections. In HTTP status codes, this is the 300 family of status codes, including:
y y y

301: Moved permanently 302: Found (the request was redirected to another URL/URI) 305: Use Proxy (the request must use a proxy to access the resource requested)

Ajax programmers probably aren't concerned about redirections for two reasons:
y

First, Ajax applications are almost always written for a specific serverside script, servlet, or application. For that component to disappear and move somewhere else without you, the Ajax programmer, knowing about it is pretty rare. So more often than not, you'll know that a

y

resource has moved (because you moved it or had it moved), change the URL in your request, and never encounter this sort of result. And an even more relevant reason is: Ajax applications and requests are sandboxed. This means that the domain that serves a Web page that makes Ajax requests is the domain that must respond to those requests. So a Web page served from ebay.com cannot make an Ajaxstyle request to a script running on amazon.com; Ajax applications on ibm.com cannot make requests to servlets running on netbeans.org.

As a result, your requests aren't able to be redirected to another server without generating a security error. In those cases, you won't get a status code at all. You'll usually just have a JavaScript error in the debug console. So, while you think about plenty of status codes, you can largely ignore the redirection codes altogether. Errors Edge cases and hard cases Once you've taken care of status code At this point, novice programmers 200 and realized you can largely might wonder what all this fuss is ignore the 300 family of status codes, about. It's certainly true that less the only other group of codes to worry than 5 percent of Ajax requests about is the 400 family, which require working with ready states indicates various types of errors. Look like 2 and 3 and status codes like back at Listing 7 and notice that while 403 (and in fact, it might be much errors are handled, it's only a very closer to 1 percent or less). These generic error message that is output cases are important and are called to the user. While this is a step in the edge cases -- situations that occur right direction, it's still a pretty useless in very unusual situations in which message in terms of telling the user or the oddest conditions are met. a programmer working on the While unusual, edge cases make up application what actually went wrong. about 80 percent of most users' First, add support for missing pages. frustrations! This really shouldn't happen much in Typical users forget the 100 times production systems, but it's not an application worked correctly, but uncommon in testing for a script to clearly remember the time it didn't. move or for a programmer to enter an If you can handle the edge cases -incorrect URL. If you can report 404 and hard cases -- smoothly, then errors gracefully, you're going to you'll have content users that provide a lot more help to confused return to your site. users and programmers. For example, if a script on the server was removed and you use the code in Listing 7, you'd see a non-descript error as shown in Figure 5. Figure 5. Generic error handling

The user has no way to tell if the problem is authentication, a missing script (which is the case here), user error, or even whether something in the code caused the problem. Some simple code additions can make this error a lot more specific. Take a look at Listing 8 which handles missing scripts as well as authentication errors with a specific message. Listing 8. Check for a valid status code 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, "<br />"); } else if (request.status == 404) { alert ("Requested URL is not found."); } else if (request.status == 403) { alert("Access denied."); } else alert("status is " + request.status); } } This is still rather simple, but it does provide some additional information.

Figure 6 shows the same error as in Figure 5, but this time the error-handling code gives a much better picture of what happened to the user or programmer. Figure 6. Specific error handling

In your own applications, you might consider clearing the username and password when failure occurs because of authentication and adding an error message to the screen. Similar approaches can be taken to more gracefully handle missing scripts or other 400-type errors (such as 405 for an unacceptable request method like sending a HEAD request that is not allowed, or 407 in which proxy authentication is required). Whatever choices you make, though, it begins with handling the status code returned from the server. Additional request types If you really want to take control of the XMLHttpRequest object, consider this one last stop -- add HEAD requests to your repertoire. In the previous two articles, I showed you how to make GET requests; in an upcoming article, you'll learn all about sending data to the server using POST requests. In the spirit of enhanced error handling and information gathering, though, you should learn how to make HEAD requests. Making the request Actually making a HEAD request is quite trivial; you simply call the open() method with "HEAD" instead of "GET" or "POST" as the first parameter, as shown in Listing 9. Listing 9. Make a HEAD request with Ajax function getSalesData() {

createRequest(); var url = "/boards/servlet/UpdateBoardSales"; request.open( "HEAD" , url, true); request.onreadystatechange = updatePage; request.send(null); } When you make a HEAD request like this, the server doesn't return an actual response as it would for a GET or POST request. Instead, the server only has to return the headers of the resource which include the last time the content in the response was modified, whether the requested resource exists, and quite a few other interesting informational bits. You can use several of these to find out about a resource before the server has to process and return that resource. The easiest thing you can do with a request like this is to simply spit out all of the response headers. This gives you a feel for what's available to you through HEAD requests. Listing 10 provides a simple callback function to output all the response headers from a HEAD request. Listing 10. Print all the response headers from a HEAD request function updatePage() { if (request.readyState == 4) { alert(request.getAllResponseHeaders()); } } Check out Figure 7, which shows the response headers from a simple Ajax application that makes a HEAD request to a server. Figure 7. Response headers from a HEAD request

You can use any of these headers (from the server type to the content type) individually to provide extra information or functionality within an Ajax application. Checking for a URL You've already seen how to check for a 404 error when a URL doesn't exist. If this turns into a common problem -- perhaps a certain script or servlet is offline quite a bit -- you might want to check for the URL before making a full GET or POST request. To do this, make a HEAD request and then check for a 404 error in your callback function; Listing 11 shows a sample callback. Listing 11. Check to see if a URL exists function updatePage() { if (request.readyState == 4) { if (request.status == 200) { alert("URL exists"); } else if (request.status == 404) { alert("URL does not exist."); } else { alert("Status is: " + request.status); } } } To be honest, this has little value. The server has to respond to the request and figure out a response to populate the content-length response header, so you don't save any processing time. Additionally, it takes just as much time to make the request and see if the URL exists using a HEAD request as it does to

make the request using GET or POST than just handling errors as shown in Listing 7. Still, sometimes it's useful to know exactly what is available; you never know when creativity will strike and you'll need the HEAD request! Useful HEAD requests One area where you'll find a HEAD request useful is to check the content length or even the content type. This allows you to determine if a huge amount of data will be sent back to process a request or if the server will try to return binary data instead of HTML, text, or XML (which are all three much easier to process in JavaScript than binary data). In these cases, you just use the appropriate header name and pass it to the getResponseHeader() method on the XMLHttpRequest object. So to get the length of a response, just call request.getResponseHeader("Content-Length");. To get the content type, use request.getResponseHeader("Content-Type");. In many applications, making HEAD requests adds no functionality and might even slow down a request (by forcing a HEAD request to get data about the response and then a subsequent GET or POST request to actually get the response). However, in the event that you are unsure about a script or serverside component, a HEAD request can allow you to get some basic data without dealing with response data or needing the bandwidth to send that response. In conclusion For many Ajax and Web programmers, the material in this article seems fairly advanced. What is the value in making a HEAD request? What is really a case where you should handle a redirection status code explicitly in your JavaScript? These are good questions; for simple applications, the answer is that these advanced techniques are unlikely to be valuable. However, the Web is no longer a place where simple applications are tolerated; users have become more advanced, customers expect robustness and advanced error reporting, and managers are fired because an application goes down 1 percent of the time. It's your job then, to go beyond a simple application and that requires a more thorough understanding of XMLHttpRequest.
y

y

y

If you can account for the various ready states -- and understand how they differ from browser to browser -- you'll be able to debug an application quickly. You might even come up with creative functionality based on a ready status and report on a request's status to users and customers. If you have a handle on status codes, you can set your application up to deal with a script's errors, unexpected responses, and edge cases. As a result, your application will work all of the time, rather than just in the situation where everything goes exactly right. Add to this the ability to make HEAD requests, check for the existence of a URL, and find out when a file was modified, and you can ensure that users get valid pages, are up-to-date on their information, and (most importantly) surprise them with just how robust and versatile your application is.

This article isn't going to make your applications flashy, help you highlight text with fading yellow spotlights, or feel more like a desktop. While these are all

strengths of Ajax (and topics we'll cover in subsequent articles), they are to some degree just icing on the cake. If you can use Ajax to build a solid foundation in which your application handles errors and problems smoothly, users will return to your site and application. Add to this the visual trickery that I'll talk about in upcoming articles and you'll have thrilled, excited, and happy customers. (Seriously, you don't want to miss the next article!) Download Description Name Size Download method

Example code for this wa-ajaxintro3_ajax-xhr_adv.zip 183KB HTTP article Information about download methods Mastering Ajax, Part 4: Exploiting DOM for Web response Convert HTML into an object model to make Web pages responsive and interactive Level: Introductory Document options Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc. Print this 14 Mar 2006 page The great divide between programmers (who work with E-mail this back-end applications) and Web programmers (who page spend their time writing HTML, CSS, and JavaScript) is Document long standing. However, the Document Object Model options (DOM) bridges the chasm and makes working with both requiring XML on the back end and HTML on the front end possible JavaScript are and an effective tool. In this article, Brett McLaughlin not displayed introduces the Document Object Model, explains its use in Web pages, and starts to explore its usage from Rate this page JavaScript. Like many Web programmers, you have probably Help us worked with HTML. HTML is how programmers start to improve this work on a Web page; HTML is often the last thing they content do as they finish up an application or site, and tweak that last bit of placement, color, or style. And, just as common as using HTML is the misconception about what exactly happens to that HTML once it goes to a browser to render to the screen. Before I dive into what you might think happens -- and why it is probably wrong -- I want you need to be clear on the process involved in designing and serving Web pages: 1. Someone (usually you!) creates HTML in a text editor or IDE. 2. You then upload the HTML to a Web server, like Apache HTTPD, and make it public on the Internet or an intranet. 3. A user requests your Web page with a browser like Firefox or Safari. 4. The user's browser makes a request for the HTML to your Web server. 5. The browser renders the page it receives from the server graphically

and textually; users look at and activate the Web page. While this feels very basic, things will get interesting quickly. In fact, the tremendous amount of "stuff" that happens between steps 4 and 5 is what the focus of this article. The term "stuff" really applies too, since most programmers never really consider exactly what happens to their markup when a user's browser is asked to display it:
y y y y

Does the browser just read the text in the HTML and display it? What about CSS, especially if the CSS is in an external file? And what about JavaScript -- again often in an external file? How does the browser handle these items and how does it map event handlers, functions, and styles to that textual markup?

It turns out that the answer to all these questions is the Document Object Model. So, without further ado, let's dig into the DOM. Web programmers and markup For most programmers, their job ends where the Web browser begins. In other words, once you drop a file of HTML into a directory on your Web server, you usually file it away as "done" and (hopefully) never really think about it again! That's a great goal when it comes to writing clean, well-organized pages, too; there's nothing wrong with wanting your markup to display what it should, across browsers, with various versions of CSS and JavaScript. The problem is that this approach limits a programmer's understanding of what really happens in the browser. More importantly, it limits your ability to update, change, and restructure a Web page dynamically using client-side JavaScript. Get rid of that limitation, and allow even greater interaction and creativity on your Web sites. What the programmer does As the typical Web programmer, you probably fire up your text editor and IDE and start to enter HTML, CSS, or even JavaScript. It's easy to think about those tags and selectors and attributes only as little tasks that you do to make a site look just right. But you need to stretch your mind beyond that point -instead, realize that you are organizing your content. Don't worry; I promise this won't turn into a lecture on the beauty of markup, how you must realize the true potential of your Web page, or anything else meta-physical. What you do need to understand is exactly what your role in Web development is. When it comes to how a page looks, at best you're only able to make suggestions. When you provide a CSS stylesheet, a user can override your style choices. When you provide a font size, a user's browser can alter those sizes for the visually impaired or scale them down on massive monitors (with equally massive resolutions). Even the colors and font faces you choose are subject to the monitor of users and the fonts that users install on their systems. While it's great to do your best in styling a page, that's not the largest impact you have on a Web page. What you do absolutely control is the structure of your Web page. Your markup is unchangeable and unalterable and users can't mess with it; their browsers can only retrieve it from your Web server and display it (albeit with a style more in line with the user's tastes than your own). But the organization

of that page -- whether this word is inside that paragraph or in the other div -is solely up to you. When it comes to actually changing your page (which is what most Ajax applications focus on), it's the structure of your page that you operate on. While it's nice to change the color of a piece of text, it's much more dramatic to add text or an entire section to an existing page. No matter how the user styles that section, you work with the organization of the page itself. What the markup does Once you realize that your markup is really about organization, you can view it differently. Rather than think that an h1 causes text to be big, black, and bold, think about an h1 as a heading. How the user sees that -- and whether they use your CSS, their own, or some combination of the two -- is a secondary consideration. Instead, realize that markup is all about providing this level of organization; a p indicates that text is in a paragraph, img denotes an image, div divides a page up into sections, and so forth. You should also be clear that style and behavior (event handlers and JavaScript) are applied to this organization after the fact. The markup has to be in place to be operated upon or styled. So, just as you might have CSS in an external file to your HTML, the organization of your markup is separate from its style, formatting, and behavior. While you can certainly change the style of an element or piece of text from JavaScript, it's more interesting to actually change the organization that your markup lays out. As long as you keep in mind that your markup only provides an organization, or framework, for your page, you're ahead of the game. And a little further on, you'll see how the browser takes all this textual organization and turns it into something much more interesting -- a set of objects, each of which can be changed, added to, or deleted. Some additional thoughts on markup Plain text editing: Right or wrong? Plain text files are ideal for storing markup, but that doesn't hold true for editing that markup. It's perfectly acceptable to use an IDE like Macromedia DreamWeaver -- or the slightly more intrusive Microsoft® FrontPage® -to work on Web page markup. These environments often offer shortcuts and help in creating Web pages, especially when you're using CSS and JavaScript, each from a file external to an actual page's markup. Many

The advantages of text markup folks still prefer good old Before I discuss the Web browser, it's worth Notepad or vi (I confess I'm considering why plain text is absolutely the one of those folk) and that's best choice for storing your HTML (for more on a great option as well. In this, see Some additional thoughts on either case, the final result markup). Without getting into the pros and is a text file full of markup. cons, simply recall that your HTML is sent Text over the network: A across a network to a Web browser every time good thing the page is viewed (putting caching and so As already mentioned, text forth aside for simplicity's sake). There's is a great medium for a simply no more efficient approach to take than document -- like HTML or passing along text. Binary objects, graphical CSS -- that is transferred representations of the page, a re-organized over a network hundreds chunk of markup ... all of these are harder to and thousands of times. send across the network than plain text files. When I say that the browser Add to that the value that a browser adds to has a hard time the equation. Today's browsers allow users to representing text, that change the size of text, scale images, means specifically turning download the CSS or JavaScript for a page (in text into the visual and most cases), and a lot more -- this all graphical page that users precludes sending any kind of graphical view. This has no bearing representation of the page to the browser. on how the browser actually Instead, the browser needs the raw HTML so it retrieves a page from a Web can apply whatever processing to the page in server; in that case, text is the browser rather than trusting the server to still very much the best handle that task. In the same vein, separating option. CSS from JavaScript and separating those from the HTML markup requires a format that is easy to, well, separate. Text files again are a great way to do just this. Last, but not least, remember that the promise of new standards like HTML 4.01 and XHTML 1.0 and 1.1 separates content (the data in your page) from presentation and style (usually applied by CSS). For programmers to separate their HTML from their CSS, then force a browser to retrieve some representation of a page that melds these all back together, defeats much of the advantage of these standards. To keep these disparate parts separate all the way down to the browser allows the browser the most flexibility in getting the HTML from the server. A closer look at Web browsers For some of you, everything you've read so far may be droll review of your role in the Web development process. But when it comes to what the Web browser does, many of the most savvy Web designers and developers often don't realize what actually goes on "under the hood." I'll focus on that in this section. And don't worry, code is coming soon, but hold off on your coding impatience because really understanding exactly what a Web browser does is essential to your code working correctly. The disadvantages of text markup Just as text markup has terrific advantages for a designer or page creator, it also has rather significant disadvantages for a browser. Specifically, browsers have a very difficult time directly representing text markup to a user visually

(for more on this, see Some additional thoughts on markup). Consider these frequent browser tasks:
y

y y y

Apply CSS styles -- often from multiple stylesheets in external files -- to markup based on the type of element, its class, its ID, and its position in the HTML document. Apply styles and formatting based on JavaScript code -- also often in external files -- to different parts of the HTML document. Change the value of form fields based on JavaScript code. Support visual effects like image rollovers and image swapping based on JavaScript code.

The complexity isn't in coding these tasks; it's fairly easy to do each of these things. The complexity comes from the browser actually carrying out the requested action. If markup is stored as text and, for example, you want to center the text (text-align: center) in a p element in the center-text class, how do you accomplish that?
y y y

Do you add inline styling to the text? Do you apply the styling to the HTML text in the browser and just keep up with which content to centered or not center? Do you apply unstyled HTML and then apply format after the fact?

These very difficult questions are why few people code browsers these days. (Those who do should receive a hearty "Thanks!") Clearly, plain text isn't a great way to store HTML for the browser even though text was a good solution for getting a page's markup in the first place. Add to this the ability for JavaScript to change the structure of a page and things really get tricky. Should the browser rewrite the modified structure to disk? How can it keep up with what the current stage of the document is? Clearly, text isn't the answer. It's difficult to modify, clumsy to apply styles and behavior to, and ultimately bears little likeness to the dynamic nature of today's Web pages. Moving to a tree view The answer to this problem -- at least, the answer chosen by today's Web browsers -- is to use a tree structure to represent HTML. Take a look at Listing 1, a rather simple and boring HTML page represented as text markup. Listing 1. Simple HTML page in text markup <html> <head> <title>Trees, trees, everywhere</title> </head> <body> <h1>Trees, trees, everywhere</h1> <p>Welcome to a <em>really</em> boring page.</p> <div> Come again soon.

<img src="come-again.gif" /> </div> </body> </html> The browser takes this and converts it into a tree-like structure, as in Figure 1. Figure 1. The tree view of Listing 1

I made a few very minor simplifications to keep this article on track. Experts in the DOM or XML will realize that whitespace can have an effect on how text in a document is represented and broken up in the Web browser's tree structure. Getting into this does little but confuse the matter, so if you know about the effect of whitespace, great; if not, read on and don't worry about it. When it becomes an issue, you'll find out all you need at that time. Other than the actual tree background, the first thing you might notice here is that everything in the tree begins with the outer-most, containing element of HTML, which is the html element. This is called the root element in keeping with the tree metaphor. So even though this is at the bottom of the tree, ialways begin here when you look at and analyze trees. If it helps, you're welcome to flip the whole thing upside down, although that does stretch the tree metaphor a bit. From the root flow out lines that show the relationships between different

pieces of markup. The head and body elements are children of the html root element; title is a child of head and then the text "Trees, trees, everywhere" is a child of title. The entire tree is organized like this until the browser gets a structure similar to what you see in Figure 1. A few additional terms To carry on with the tree metaphor, head and body are said to be branches of html. They are branches because they in turn have children of their own. When you reach the extremities of the tree, you'll run into mostly text such as "Trees, trees, everywhere" and "really." These are often referred to leaves because they have no children of their own. You don't need to memorize all these terms and it is often easier to just visualize the tree structure when you try to figure out what a particular term means. The value of objects Now that you have some basic terminology in hand, it's time to focus more on those little rectangles with element names and text inside (Figure 1). Each rectangles is an object; that's where the browser resolves some of these problems with text. By using objects to represent each piece of the HTML document, it becomes very easy to change the organization, apply styles, allow JavaScript to access the document, and much more. Object types and properties Each possible type of markup gets its own object type. For instance, elements in your HTML are represented by an Element object type. The text in your document is represented by a Text type, attributes are represented by Attribute types, and right on down the line. So the Web browser not only gets to use an object model to represent your document -- getting away from having to deal with static text -- but can immediately tell what something is by its object type. The HTML document is parsed and turned into the set of objects like you saw in Figure 1 and then things like angle brackets and escape sequences (for example, using < for < and > for >) no longer become an issue. This makes the job of the browser, at least after it parses the input HTML, much easier. The operation to figure out whether something is an element or an attribute and then determine what to do with that type of object is simple. By using objects, the Web browser can then change those objects' properties. For example, each element object has a parent and a list of children. So adding a new child element or text is simply a matter of adding a new child to an element's list of children. These objects also have a style property, so it becomes trivial to change the style of an element or piece of text on the fly. For example, you might change the height of a div using JavaScript like this: someDiv.style.height = "300px"; In other words, the Web browser can very easily change the appearance and structure of the tree using object properties like this. Compare this to the complicated sorts of things that the browser must do if it represented the page as text internally; every change of property or structure requires the browser to rewrite the static file, re-parse it, and re-display it on the screen. All of this becomes possible with objects. At this point, take time to pull open some of your HTML documents and sketch

them out as trees. While that seems an unusual request -- especially from an article that contains very little code -- you will need to become familiar with the structure of these trees if you want to be able to manipulate them. In the process, you'll probably find some oddities. For example, consider the following situations:
y y y

What happens to attributes? What about text that is broken up with elements, like em and b? And what about HTML that isn't structured correctly (like when a closing p tag is missing)?

Once familiar with these sorts of issues, you'll understand the next few sections a lot better. Strict is sometimes good If you tried the exercise I just mentioned, you probably found some of the potential troubles for a tree-view of your markup (if you didn't exercise, just take my word for it!). In fact, you'll find several of these in Listing 1 and Figure 1, starting with the way the p element was broken up. If you ask the typical Web developer what the text content of the p element is, the most common answer would be, "Welcome to a really boring Web page." If you compare this with Figure 1, you'll see that this answer -- although logical -isn't at all correct. It turns out that the p element has three different child objects and none contain all of the text "Welcome to a really boring Web page." You'll find parts of that text, like "Welcome to a " and " boring Web page", but not all of it. To understand this, remember that everything in your markup has to be turned into an object of some type. Furthermore, the order does matter! Can you imagine how users would respond to a Web browser if it showed the correct markup, but in a different ordering than you provided in your HTML? Paragraphs were sandwiched in between titles and headings, even when that's not how you organized the document yourself? Obviously, the browser must preserve the order of elements and text. In this case, the p element has three distinct parts:
y y y

The text that comes before the em element Tthe em element itself The text that comes after the em element

If you mix this ordering up, you might apply the emphasis to the wrong portion of text. To keep this all straight, the p element has three object children in the order that those things appeared in the HTML in Listing 1. Further, the emphasized text "really" isn't a child element of p; it is a child of em which is a child of p. It is very important for you to understand this concept. Even though the "really" text will probably display along with the rest of the p element's text, it still is a direct child of the em element. It can have different formatting from the rest of the p and can be moved around independently of the rest of the text.

To help cement this in your mind, try to diagram the HTML in Listings 2 and 3, making sure you keep text with its correct parent (despite how that text might end up looking on screen). Listing 2. Markup with slightly tricky element nesting <html> <head> <title>This is a little tricky</title> </head> <body> <h1>Pay <u>close</u> attention, OK?</h1> <div> <p>This p really isn't <em>necessary</em>, but it makes the <span id="bold-text">structure <i>and</i> the organization</span> of the page easier to keep up with.</p> </div> </body> </html>

Listing 3. Even trickier nesting of elements <html> <head> <title>Trickier nesting, still</title> </head> <body> <div id="main-body"> <div id="contents"> <table> <tr><th>Steps</th><th>Process</th></tr> <tr><td>1</td><td>Figure out the <em>root element</em>.</td></tr> <tr><td>2</td><td>Deal with the <span id="code">head</span> first, as it's usually easy.</td></tr> <tr><td>3</td><td>Work through the <span id="code">body</span>. Just <em>take your time</em>.</td></tr> </table> </div> <div id="closing"> This link is <em>not</em> active, but if it were, the answers to this <a href="answers.html"><img src="exercise.gif" /></a> would be there. But <em>do the exercise anyway!</em> </div> </div>

</body> </html> You'll find the answers to these exercises in the GIF files tricky-solution.gif in Figure 2 and trickier-solution.gif in Figure 3 at the end of this article. Don't peek until you take the time to work these out for yourself. It will help you understand how strictly rules apply to organizing the tree and really help you in your quest to master HTML and its tree structure. What about attributes? Did you run across any problems as you tried to figure out what to do with attributes? As I mentioned, attributes do have their own object type, but an attribute is really not the child of the element it appears on -- nested elements and text are not at the same "level" of an attribute and you'll notice that the answers to the exercises in Listings 2 and 3 do not have attributes shown. Attributes are in fact stored in the object model that a browser uses, but they are a bit of a special case. Each element has a list of attributes available to it, separate from the list of child objects. So a div element might have a list that contained an attribute named "id" and another named "class." Keep in mind that attributes for an element must have unique names; in other words, an element cannot have two "id" or two "class" attributes. This makes the list very easy to keep up with and to access. As you'll see in the next article, you can simply call a method like getAttribute("id") to get the value of an attribute by its name. You can also add attributes and set (or reset) the value of existing attributes with similar method calls. It's also worth pointing out that the uniqueness of attribute names makes this list different than the list of child objects. A p element could have multiple em elements within it, so the list of child objects can contain duplicate items. While the list of children and the list of attributes operate similarly, one can contain duplicates (the children of an object) and one cannot (the attributes of an element object). Finally, only elements can have attributes, so text objects have no lists attached to them for storing attributes. Sloppy HTML Before I move on, one more topic is worth some time when it comes to how the browser converts markup to a tree representation -- how a browser deals with markup that is not well-formed. Well-formed is actually a term largely used in XML and means two basic things:
y y

Every opening tag has a matching closing tag. So every <p> is matched in the document by a </p>, every <div> by a </div>, and so forth. The innermost opening tag is matched with the innermost closing tag, then the next innermost opening tag by the next innermost closing tag, and so forth. So <b><i>bold and italics</b></i> would be illegal because the innermost opening tag -- <i> -- is improperly matched with the innermost closing tag -- <b>. To make this well-formed, you would need to switch either the opening tag order or the closing tag order. (If you switched both, you'd still have a problem).

Study these two rules closely. They are both rules that not only increase the

simple organization of a document, but they also remove ambiguity. Should bolding be applied first and then italics? Or the other way around? If it seems that this ordering and ambiguity is not a big deal, remember that CSS allows rules to override other rules so if, for example, the font for text within b elements was different than the font for within i elements, the order in which formatting was applied becomes very important. Therefore, the wellformedness of an HTML page comes into play. In cases where a browser receives a document that is not well-formed, it simply does the best it can. The resulting tree structure is at best an approximation of what the original page author intended and at worst something completely different. If you ever loaded your page in a browser and saw something completely unexpected, you might have viewed the result of a browser trying to guess what your structure should be and doing the job poorly. Of course, the fix to this is pretty simple: Make sure your documents are well-formed! If you're unclear on how to write standardized HTML like this, consult the Resources for help. Introducing the DOM So far you've heard that browsers turn a Web page into an object representation and maybe you've even guessed that the object representation is a DOM tree. DOM stands for Document Object Model and is a specification available from the World Wide Web Consortium (W3C) (you can check out several DOM-related links in the Resources). More importantly though, the DOM defines the objects' types and properties that allow a browser to represent markup. (The next article in this series focuses on the specifics of using the DOM from your JavaScript and Ajax code.) The document object First and foremost, you will need to access the object model itself. This is remarkably easy; to use the built-in document variable in any piece of JavaScript code running on your Web page, you can write code like this: var domTree = document; Of course, this code is pretty useless in and of itself, but it does demonstrates that every Web browser makes the document object available to JavaScript code and that the object represents the complete tree of markup (Figure 1). Everything is a node Clearly, the document object is important, but is just the beginning. Before you can go further, you need to learn another term: node. You already know that each bit of markup is represented by an object, but it's more than just any object -- it's a specific type of object, a DOM node. The more specific types -like text, elements, and attributes -- extend from this basic node type. So you have text nodes, element nodes, and attribute nodes. If you've programmed much in JavaScript, it should occur to you that you might already be using DOM code. If you followed this Ajax series thus far, then you've definitely used DOM code for some time now. For example, the line var number = document.getElementById("phone").value; uses the DOM to find a specific element and then to retrieve the value of that element (in this case, a form field). So even if you didn't realize it, you used the DOM every time you

typed document into your JavaScript code. To refine the terms you've learned then, a DOM tree is a tree of objects, but more specifically it is a tree of node objects. In Ajax applications -- or any other JavaScript -- you can work with those nodes to create such effects as removing an element and its content, highlighting a certain piece of text, or adding a new image element. Since this all occurs on the client side (code that runs in your Web browser), these effects take place immediately without communication with the server. The end result is often an application that feels more responsive because things on the Web page change without long pauses while a request goes to a server and a response is interpreted. In most programming languages, you need to learn the actual object names for each type of node, learn the properties available, and figure out about types and casting; but none of this is necessary in JavaScript. You can simply create a variable and assign it the object you want (as you've already seen): var domTree = document; var phoneNumberElement = document.getElementById("phone"); var phoneNumber = phoneNumberElement.value; There are no types and JavaScript handles creating the variables and assigning them the correct types as needed. As a result, it becomes fairly trivial to use the DOM from JavaScript (a later article focuses on the DOM in relation to XML and things are a little trickier). In conclusion At this point, I'm going to leave you with a bit of a cliffhanger. Obviously, this hasn't been a completely exhaustive coverage of the DOM; in fact, this article is little more than an introduction to the DOM. There is more to DOM than I've shown you today! The next article in this series will expand upon these ideas and dive more into how you can use the DOM in your JavaScript to update Web pages, make changes to your HTML on the fly, and create a more interactive experience for your user. I'll come back to DOM once again in later articles which focus on using XML in your Ajax requests. So become familiar with the DOM; it's a major part of Ajax applications. It would be pretty simple to launch into more of the DOM at this point, detailing how to move within a DOM tree, get the values of elements and text, iterate through node lists, and more, but that would probably leave you with the impression that the DOM is about code -- it's not. Before the next article, try to think about tree structures and work through some of your own HTML to see how a Web browser would turn that HTML into a tree view of the markup. Also, think about the organization of a DOM tree and work through the special cases discussed in this article: attributes, text that has elements mixed in with it, elements that don't have text content (like the img element). If you get a firm grasp of these concepts and then learn the syntax of JavaScript and the DOM (in the next article), it will make crafting responsiveness much easier. And don't forget, here are the answers to Listings 2 and 3 -- they are also included with the sample code!

Figure 2. The answer to Listing 2

Figure 3. The answer to Listing 3

Mastering Ajax, Part 5: Manipulate the DOM Use JavaScript to update your Web pages on the fly Level: Introductory Document options Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc. Print this 11 Apr 2006 page Last month Brett introduced the Document Object E-mail this Model, whose elements work behind the scenes to page define your Web pages. This month he dives even Document deeper into the DOM. Learn how to create, remove, options and change the parts of a DOM tree, and take the next requiring step toward updating your Web pages on the fly! JavaScript If you followed my discussion in this series last are not month, then you got a first-hand look at what goes on displayed when a Web browser displays one of your Web pages. As I explained then, when the HTML and CSS you've Rate this page defined for your page is sent to a Web browser, it's translated from text to an object model. This is true Help us whether the code is simple or complex, housed all in improve this one file or in separate files. The browser then works content directly with the object model, rather than the text files you supplied. The model the browser uses is called the Document Object Model. It connects objects representing the elements, attributes, and text in your documents. All the styles, values, and even most of the spaces in your HTML and CSS are incorporated into the object model. The specific model for a given Web page is called the page's DOM tree. Understanding what a DOM tree is, and even knowing how it represents your HTML and CSS, is just the first step in taking control of your Web pages. Next, you need to learn how to work with the DOM tree for a particular Web page. For instance, if you add an element to the DOM tree, that element immediately appears in a user's Web browser -- without the page reloading. Remove some text from the DOM tree, and that text vanishes from the user's screen. You can change and interact with the user interface through the DOM, which gives you tremendous programming power and flexibility. Once you learn how to work with a DOM tree you've taken a huge leap toward mastering rich, interactive, dynamic Web sites. Note that the following discussion builds on last month's "Exploiting the DOM for Web response;" if you haven't read that article, you might want to do so before you proceed here. Acronym pronunciation matters In many ways, the Document Object Model could just as easily have been called the Document Node Model. Of course, most people don't know what the term node means, and "DNM" isn't

Cross browser, cross language nearly as easy to pronounce as The Document Object Model is a W3C "DOM," so it's easy to understand standard (see Resources for links to why the W3C went with DOM. the W3C). Because of that, all modern Web browsers support the DOM, at least to some degree. While there is some variance among browsers, if you use core DOM functionality -- and pay attention to a few special cases and exceptions -- your DOM code will work on any browser in the same way. The code you write to modify a Web page in Opera will work on Apple's Safari®, Firefox®, Microsoft® Internet Explorer®, and Mozilla®. The DOM is also a cross-language specification; in other words, you can use it from most of the popular programming languages. The W3C defines several language bindings for the DOM. A language binding is simply an API defined to let you use the DOM for a specific language. For example, you can find well-defined DOM language bindings for C, Java, and JavaScript. So you can use the DOM from any of these languages. Language bindings are also available for several other languages, although many of these are not defined by the W3C, but instead by third parties. In this series I'll focus on the JavaScript bindings into the DOM. That makes sense because most asynchronous application development is based on writing JavaScript code to run in a Web browser. With JavaScript and the DOM, you can modify the user interface on the fly, respond to user events and input, and more -- all using fairly standardized JavaScript. All that said, I do encourage you to check out the DOM language bindings in other languages. For instance, you can use the Java language bindings to work not only with HTML, but also XML, as I'll discuss in a later article. So the lessons you'll learn here apply to far more than HTML, in many more environments than just client-side JavaScript.

Back to top The conceptual node A node is the most basic object type in the DOM. In fact, as you'll see in this article, almost every other object defined by the DOM extends the node object. But, before you get too far into semantics, you need to understand the concept that is represented by a node; then, to learn the actual properties and methods of a node is a piece of cake. In a DOM tree, almost everything you'll come across is a node. Every element is at its most basic level a node in the DOM tree. Every attribute is a node. Every piece of text is a node. Even comments, special characters (like &copy;, which represents a copyright symbol), and a DOCTYPE declaration (if you have one in your HTML or XHTML) all are nodes. So before I get into the specifics of each of these individual types, you really need to grasp what a node is. A node is... In simplest terms, a node is just one single thing in a DOM tree. The vagueness of "thing" is intentional, because that's about as specific as it gets. For example, it's probably not obvious that an element in your HTML, like img, and a piece of text in HTML, like "Scroll down for more details" have

much in common. But that's because you're probably thinking about the function of those individual types, and focusing on how different they are. Consider, instead, that each element and piece of text in a DOM tree has a parent; that parent is either the child of another element (like when an img is nested inside a p element), or is the top-most element in the DOM tree (which is a one-time special case for each document, and is where you use the html element). Also consider that both elements and text have a type. The type for an element is obviously an element; the type for text is text. Each node also has some fairly well-defined structure to it: does it have a node (or nodes) below it, such as child elements? Does it have sibling nodes (nodes "next to" the element or text)? What document does each node belong to? Obviously, much of this sounds pretty abstract. In fact, it might even seem silly to say that the type of an element is ... well ... an element. However, you need to think a bit abstractly to realize the value of having the node as a common object type. The common node type The single task you'll perform more than any other in your DOM code is navigating within the DOM tree for a page. For instance, you might locate a form by its "id" attribute, and then begin to work with the elements and text nested within that form. There will be textual instructions, labels for input fields, actual input elements, and possibly other HTML elements like img elements and links (a elements). If elements and text are completely different types, then you have to write completely different pieces of code to move from one type to another. Things are different if you use a common node type. In that case you can simply move from node to node, and worry about the type of the node only when you want to do something specific with an element or text. When you just move around in the DOM tree, you'll use the same operations to move to an element's parent -- or its children -- as you would with any other type of node. You only have to work specifically with a node type, like an element or text, when you require something specific from a certain type of node, like an element's attributes. Thinking about each object in the DOM tree simply as a node allows you to operate much more simply. With that in mind, I'll look next at exactly what the DOM Node construct has to offer, starting with properties and methods.

Back to top Properties of a node You'll want to use several properties and methods when you work with DOM nodes, so let's consider them first. The key properties of a DOM node are:
y y y y

nodeName reports the name of the node (see more below). nodeValue:gives the "value" of the node (see more below). parentNode returns the node's parent. Remember, every element, attribute, and text has a parent node. childNodes is a list of a node's children. When working with HTML, this list is only useful when you're dealing with an element; text nodes and

y y y

y y

attribute nodes don't have any children. firstChild is just a shortcut to the first node in the childNodes list. lastChild is another shortcut, this time to the last node in the childNodes list. previousSibling returns the node before the current node. In other words, it returns the node that precedes the current one, in this node's parent's childNodes list (if that was confusing, re-read that last sentence). nextSibling is similar to the previousSibling property; it turns the next node in the parent's childNodes list. attributes is only useful on an element node; it returns a list of an element's attributes.

The few other properties really apply to more generic XML documents, and aren't of much use when you work with HTML-based Web pages. Unusual properties Most of the above-defined properties are pretty self-explanatory, with the exception of the nodeName and nodeValue properties. Rather than simply explain these properties, consider a couple of odd questions: What would the nodeName be for a text node? And, similarly, What would the nodeValue be for an element? If these questions stumped you, then you already understand the potential for confusion inherent in these properties. nodeName and nodeValue really don't apply to all node types (this is also true of a few of the other properties on a node). This illustrates a key concept: any of these properties can return a null value (which sometimes shows up in JavaScript as "undefined"). So, for example, the nodeName property for a text node is null (or "undefined" in some browsers, as text nodes don't have a name. nodeValue returns the text of the node, as you would probably expect. Similarly, elements have a nodeName -- the name of the element -- but the value of an element's nodeValue property is always null. Attributes have values for both the nodeName and nodeValue properties. I'll talk about these individual types a bit more in the next section, but since these properties are part of every node, they're worth mentioning here. Now take a look at Listing 1, which shows several of the node properties in action. Listing 1. Using node properties in the DOM

// These first two lines get the DOM tree for the current Web page, // and then the <html> element for that DOM tree var myDocument = document; var htmlElement = myDocument.documentElement; // What's the name of the <html> element? "html" alert("The root element of the page is " +

htmlElement.nodeName ); // Look for the <head> element var headElement = htmlElement.getElementsByTagName("head")[0]; if (headElement != null) { alert("We found the head element, named " + headElement.nodeName ); // Print out the title of the page var titleElement = headElement.getElementsByTagName("title")[0]; if (titleElement != null) { // The text will be the first child node of the <title> element var titleText = titleElement.firstChild; // We can get the text of the text node with nodeValue alert("The page title is '" + "'"); } // After <head> is <body> var bodyElement = headElement.nextSibling ; titleText.nodeValue +

while ( bodyElement.nodeName .toLowerCase() != "body") { bodyElement = } // We found the <body> element... // We'll do more when we know some methods on the nodes. } bodyElement.nextSibling ;

Back to top Methods of a node Next up are the methods available to all nodes (as in the case of node properties, I've omitted a few methods that don't really apply to most HTML DOM operations):
y

y y

insertBefore(newChild, referenceNode) inserts the newChild node before the referenceNode. Keep in mind you would call this on the intended parent of newChild. replaceChild(newChild, oldChild) replaces the oldChild node with the newChild node. removeChild(oldChild) removes the oldChild node from the node the

y y y

function is run on. appendChild(newChild) adds the newChild node to the node this function is run on. newChild is added at the end of the target node's children. hasChildNodes() returns true if the node it's called on has children, and false if it doesn't. hasAttributes() returns true if the node it's called on has attributes, and false if there are no attributes.

You'll notice that, for the most part, all of these methods deal with the children of a node. That's their primary purpose. If you're just trying to grab the value of a text node or the name of an element, you probably won't find yourself calling methods much, since you can simply use the properties of a node. Listing 2 builds on the code from Listing 1 using several of the above methods. Listing 2. Using node methods in the DOM

// These first two lines get the DOM tree for the current Web page, // and then the <html> element for that DOM tree var myDocument = document; var htmlElement = myDocument.documentElement; // What's the name of the <html> element? "html" alert("The root element of the page is " + htmlElement.nodeName); // Look for the <head> element var headElement = htmlElement.getElementsByTagName("head")[0]; if (headElement != null) { alert("We found the head element, named " + headElement.nodeName); // Print out the title of the page var titleElement = headElement.getElementsByTagName("title")[0]; if (titleElement != null) { // The text will be the first child node of the <title> element var titleText = titleElement.firstChild; // We can get the text of the text node with nodeValue alert("The page title is '" + titleText.nodeValue + "'"); } // After <head> is <body> var bodyElement = headElement.nextSibling; while (bodyElement.nodeName.toLowerCase() != "body") { bodyElement = bodyElement.nextSibling; }

// We found the <body> element... // Remove all the top-level <img> elements in the body if ( bodyElement.hasChildNodes() ) { for (i=0; i<bodyElement.childNodes.length; i++) { var currentNode = bodyElement.childNodes[i]; if (currentNode.nodeName.toLowerCase() == "img") { bodyElement.removeChild(currentNode) ; } } } } Test me! So far, you've seen just two examples, in Listings 1 and 2, but they should give you all sorts of ideas for what's possible when you start manipulating the DOM tree. If you want to try out the code so far, just drop Listing 3 into an HTML file, save it, and load it into your Web browser. Listing 3. An HTML file with some JavaScript code using the DOM

<html> <head> <title>JavaScript and the DOM</title> <script language="JavaScript"> function test() { // These first two lines get the DOM tree for the current Web page, // and then the <html> element for that DOM tree var myDocument = document; var htmlElement = myDocument.documentElement; // What's the name of the <html> element? "html" alert("The root element of the page is " + htmlElement.nodeName); // Look for the <head> element var headElement = htmlElement.getElementsByTagName("head")[0]; if (headElement != null) { alert("We found the head element, named " + headElement.nodeName); // Print out the title of the page var titleElement = headElement.getElementsByTagName("title")[0]; if (titleElement != null) { // The text will be the first child node of the <title>

element var titleText = titleElement.firstChild; // We can get the text of the text node with nodeValue alert("The page title is '" + titleText.nodeValue + "'"); } // After <head> is <body> var bodyElement = headElement.nextSibling; while (bodyElement.nodeName.toLowerCase() != "body") { bodyElement = bodyElement.nextSibling; } // We found the <body> element... // Remove all the top-level <img> elements in the body if (bodyElement.hasChildNodes()) { for (i=0; i<bodyElement.childNodes.length; i++) { var currentNode = bodyElement.childNodes[i]; if (currentNode.nodeName.toLowerCase() == "img") { bodyElement.removeChild(currentNode); } } } } } </script> </head> <body> <p>JavaScript and DOM are a perfect match. You can read more in <i>Head Rush Ajax</i>.</p> <img src="http://www.headfirstlabs.com/Images/hraj_cover150.jpg" /> <input type="button" value="Test me!" onClick="test();" /> </body> </html> Once you've loaded this page into your browser, you should see something like the page in Figure 1. Figure 1. A simple HTML page with a button to run the JavaScript

Click Test me! and you'll start to see the alert boxes, as shown in Figure 2. Figure 2. Alert boxes showing the name of an element, using nodeValue

When the code is finished running the images are removed from the page in real-time, as shown in Figure 3. Figure 3. Images removed in real-time using JavaScript

Back to top API design notes Take a look again at the properties and methods available on each node. They illustrate a key point of the DOM for those comfortable with objectoriented (OO) programming: the DOM isn't a very object-oriented API. First, in many cases you'll use an object's properties directly, rather than calling a method on a node object. There's no getNodeName() method, for example; you just use the nodeName property directly. So node objects (as well as the other DOM objects) expose a lot of their data through properties, and not just functions. Second, the naming of objects and methods in the DOM might seem a bit strange if you're used to working with overloaded objects and object-oriented APIs, especially in languages like Java or C++. The DOM has to work in C, Java, and JavaScript (to name a few languages), so some concessions were made in the design of the API. For instance, you'll see two different methods on the NamedNodeMap methods that look like this:
y y

getNamedItem(String name) getNamedItemNS(Node node)

For OO programmers, this looks pretty odd. Two methods, with the same purpose, but one takes a String and one takes a Node. In most OO APIs, you would use the same method name for both versions. The virtual machine running your code would figure out which method to run based on the type of object you passed into the method.

The problem is that JavaScript doesn't support this technique, called method overloading. In other words, JavaScript requires that you have a single method or function for a given name. So if you have a method called getNamedItem() that takes a string, then you can't have any other method or function named getNamedItem(), even if the second version takes a different type of argument (or even takes an entirely different set of arguments). JavaScript will report an error if you do, and your code won't behave as you think it should. In essence, the DOM consciously avoids method overloading and other OO programming techniques. It does this to ensure that the API works across multiple languages, including those that don't support OO programming techniques. The end result is simply that you'll have to learn a few extra method names. The upside is that you can learn the DOM in any language -for example, Java -- and know that the same method names and coding constructs will work in other languages that have a DOM implementation -like JavaScript. Let the programmer beware If you're into API design at all -- or perhaps just are paying close attention -you might wonder: "Why are properties on the node type that aren't common to all nodes?" That's a good question, and the answer is more about politics and decision-making than any technical reason. In short, the answer is, "Who knows! But it's a bit annoying, isn't it?" The property nodeName is meant to allow every type to have a name; but in many cases, that name is either undefined or it's some strange, internal name that has no value to programmers (for example, in Java, the nodeName of a text node is reported as "#text" in a lot of cases). Essentially, you have to assume that error handling is left up to you. It's not safe to simply access myNode.nodeName and then use that value; in many cases, the value will be null. So, as is often the case when it comes to programming, let the programmer beware.

Back to top Common node types Now that you've seen some of the features and properties of a DOM node (and some of its oddities as well), you're ready to learn about some of the specific types of nodes that you'll work with. In most Web applications, you'll only work with four types of nodes:
y y y y

The document node represents an entire HTML document. Element nodes represent HTML elements like a or img. Attribute nodes represent the attributes on HTML elements, like href (on the a element) or src (on the img element). Text nodes represent text in the HTML document, like "Click on the link below for a complete set list." This is the text that appears inside elements like p, a, or h2.

When you deal with HTML, you'll work with these node types about 95% of

the time. So I'll spend the remainder of this month's article discussing them in-depth. (When I discuss XML in a future article I'll introduce you to some other node types.)

Back to top The document node The first node type is one you'll use in almost every piece of DOM-based code you write: the document node. The document node is actually not an element in an HTML (or XML) page, but the page itself. So in an HTML Web page, the document node is the entire DOM tree. In JavaScript, you can access the document node by using the document keyword: // These first two lines get the DOM tree for the current Web page, // and then the <html> element for that DOM tree var myDocument = document ; var htmlElement = myDocument.documentElement;

The document keyword in JavaScript returns the DOM tree for the current Web page. From there, you can work with all the nodes in the tree. You can also use the document object to create new nodes, using methods like these:
y y y

createElement(elementName) creates an element with the supplied name. createTextNode(text) creates a new text node with the supplied text. createAttribute(attributeName) creates a new attribute with the supplied name.

The key thing to note is that these methods create nodes, but do not attach them or insert them into any particular document. For this, you have to use one of the methods you've already seen, like insertBefore() or appendChild(). So you might use code like the following to create and then add a new element to a document: var pElement = myDocument.createElement("p"); var text = myDocument.createTextNode("Here's some text in a p element."); pElement.appendChild(text); bodyElement.appendChild(pElement);

Once you've used the document element to get access to a Web page's DOM tree, you're ready to start working with elements, attributes, and text directly.

Back to top Element nodes Although you'll work with element nodes a lot, many of the operations you need to perform on elements involve the methods and properties common to all nodes, rather than methods and properties specific to just elements. Only two sets of methods are specific to elements: 1. Methods that relate to working with attributes: o getAttribute(name) returns the value of the attribute named name. o removeAttribute(name) removes the attribute named name. o setAttribute(name, value) creates an attribute named name, and sets its value to value. o getAttributeNode(name) returns the attribute node named name (attribute notes are covered below). o removeAttributeNode(node) removes the attribute node that matches the supplied node. 2. Methods that relate to finding nested elements: o getElementsByTagName(elementName) returns a list of element nodes with the supplied name. These are all pretty self-explanatory, but check out some examples anyway. Working with attributes Working with attributes is fairly simple; for example, you might create a new img element with the document object, and element, and some of the methods from above: var imgElement = document.createElement("img"); imgElement.setAttribute("src", "http://www.headfirstlabs.com/Images/hraj_cover-150.jpg"); imgElement.setAttribute("width", "130"); imgElement.setAttribute("height", "150"); bodyElement.appendChild(imgElement);

This should look pretty routine by now. In fact, you should start to see that once you understand the concept of a node and know the methods available, working with the DOM in your Web pages and JavaScript code is simple. In the code above, the JavaScript creates a new img element, sets up some attributes, and then adds it to the body of the HTML page. Finding nested elements It's also easy to find nested elements. For example, here's the code I used to find and remove all the img elements in the HTML page from Listing 3: // Remove all the top-level <img> elements in the body if (bodyElement.hasChildNodes()) { for (i=0; i<bodyElement.childNodes.length; i++) {

var currentNode = bodyElement.childNodes[i]; if (currentNode.nodeName.toLowerCase() == "img") { bodyElement.removeChild(currentNode); } } }

You could achieve a similar effect using getElementsByTagName(): // Remove all the top-level <img> elements in the body var imgElements = bodyElement.getElementsByTagName("img"); for (i=0; i<imgElements.length; i++) { var imgElement = imgElements.item[i]; bodyElement.removeChild(imgElement); }

Back to top Attribute nodes The DOM represents attributes as nodes, and you can always get an element's attributes using the attributes property of an element, as shown here: // Remove all the top-level <img> elements in the body var imgElements = bodyElement.getElementsByTagName("img"); for (i=0; i<imgElements.length; i++) { var imgElement = imgElements.item[i]; // Print out some information about this element var msg = "Found an img element!"; var atts = imgElement.attributes; for (j=0; j<atts.length; j++) { var att = atts.item(j); msg = msg + "\n " + att.nodeName + ": '" + att.nodeValue + "'"; } alert(msg); bodyElement.removeChild(imgElement); }

It's worth noting that the attributes property is actually on the node type, and not specifically on the element type. A little odd, and it won't affect your coding, but it is worth knowing. While it's certainly possible to work with attribute nodes, it's often easier to use the methods available on the element class to work with attributes. The methods are as follows:
y

y y

getAttribute(name) returns the value of the attribute named name. removeAttribute(name) removes the attribute named name. setAttribute(name, value) creates an attribute named name and sets its value to value.

These three methods don't require you to work directly with attribute nodes. Instead, you can just set and remove attributes and their values with simple string properties.

The strange case of attributes Attributes are a bit of a special case when it comes to the DOM. On the one hand, attributes really aren't children of elements like other elements or text are; in other words, they don't appear "underneath" an element. At the same time, they obviously have a relationship to an element; an element "owns" its attributes. The DOM uses nodes to represent attributes, and makes them available on an element through a special list. So attributes are part of the DOM tree, but they often don't appear on the tree. Suffice it to say that the relationship of attributes to the rest of a DOM tree's structure is a little fuzzy.

Back to top Text nodes The last type of node you need to worry about -- at least in working with HTML DOM trees -- is the text node. Almost all of the properties you'll commonly use to work with text nodes are actually available on the node object. In fact, you'll generally use the nodeValue property to get the text from a text node, as shown here: var pElements = bodyElement.getElementsByTagName("p"); for (i=0; i<pElements.length; i++) { var pElement = pElements.item(i); var text = pElement.firstChild.nodeValue; alert(text); } A few other methods are specific to text nodes. These deal with adding to or splitting the data in a node:
y y y

appendData(text) adds the text you supply to the end of the text node's existing text. insertData(position, text) allows you to insert data in the middle of the text node. It inserts the text you supply at the position indicated. replaceData(position, length, text) removes the characters starting from the

position indicated, of the length indicated, and puts the text you supply to the method in the place of the removed text.

Back to top What type of node? Most of what you've seen so far assumes you already know what type of node you're working with, which isn't always the case. For example, if you're navigating through a DOM tree, and working with the common node types, you might not know whether you've moved to an element or text. You might get all the children of a p element, and be unsure whether you're working with text, or a b element, or perhaps an img element. In these cases, you'll need to figure out what type of node you have before you can do much with it. Fortunately, it's pretty simple to figure this out. The DOM node type defines several constants, like this: 1. 2. 3. 4. Node.ELEMENT_NODE is the constant for the element node type. Node.ATTRIBUTE_NODE is the constant for the attribute node type. Node.TEXT_NODE is the constant for the text node type. Node.DOCUMENT_NODE is the constant for the document node type.

There are a number of other node types, but you'll rarely deal with any but these four when processing HTML. I've also intentionally left out the value for each of these constants, even though the values are defined in the DOM specification; you should never deal directly with the value, since that's what the constants are for! The nodeType property You can also use the nodeType property -- which is defined on the DOM node type, so is available to all nodes -- to compare a node to the above constants, as shown here: var someNode = document.documentElement.firstChild; if (someNode.nodeType == Node.ELEMENT_NODE) { alert("We've found an element node named " + someNode.nodeName); } else if (someNode.nodeType == Node.TEXT_NODE) { alert("It's a text node; the text is " + someNode.nodeValue); } else if (someNode.nodeType == Node.ATTRIBUTE_NODE) { alert("It's an attribute named " + someNode.nodeName + " with a value of '" + someNode.nodeValue + "'"); } This is a pretty simple example, but that's largely the point: getting the type of a node is simple. What's trickier is figuring out what to do with the node once you know what type it is; but with a firm knowledge of what the node, text, attribute, and elements types offer, you're ready to take on DOM

programming yourself. Well, almost. A wrench in the works It sounds like the nodeType property is just the ticket to working with nodes - it allows you to figure out what type of node you're working with, and then write the code to deal with that node. The problem is that the above-defined Node constants don't work properly on Internet Explorer. So, if you use Node.ELEMENT_NODE, Node.TEXT_NODE, or any of the other constants in your code, Internet Explorer will return an error like the one you see in Figure 4. Figure 4. Internet Explorer reports an error

Internet Explorer will report this error anytime you use the Node constants in your JavaScript. Because most of the world still uses Internet Explorer, you'd do well to avoid constructs like Node.ELEMENT_NODE or Node.TEXT_NODE in your code. Even though Internet Explorer 7.0 -- the upcoming version of Internet Explorer -- is supposed to rectify this problem, it will be a number of years before Internet Explorer 6.x falls out of heavy use. So avoid using Node; it's important that your DOM code (and your Ajax apps) work on all the major browsers.

Back to top In conclusion Are you ready for the top? If you really work to understand and eventually master the DOM, you'll be at the very top of the Web programming skill level. Most Web programmers know how to use JavaScript to write image rollovers

You've learned quite a bit in the last or grab values from a form, and few articles in this series. At this some even are comfortable making point, you should not sit back and requests and receiving responses wait for the next article, expecting from a server (as you certainly that I'll go into all sorts of clever uses should be after the first few articles for the DOM tree. Explore how you in this series). But actually can create fancy effects or slick changing the structure of a Web interfaces using the DOM is your page on the fly is not for the faint homework now. Take what you've of heart or the inexperienced. learned in these last two articles and start to experiment and play around. See if you can create a Web site that feels a bit more like a desktop application, where objects move around on the screen in response to a user's action. Better yet, throw a border around every object on the screen, so you can see where the objects in the DOM tree are, and start moving things around. Create nodes and append them to existing child lists; remove nodes that have lots of nested nodes; change the CSS style of a node, and see if those changes are inherited by child nodes. The possibilities are limitless, and every time you try something new, you'll learn something new. Enjoy playing around with your Web pages. Then, in the upcoming final part of this DOM-specific trilogy, I will show you how to incorporate some cool and interesting applications of the DOM into your programming. I'll stop speaking conceptually and explaining the API, and show you some code. Until then, come up with some clever ideas on your own, and see what you can make happen all by yourself.

Mastering Ajax, Part 6: Build DOM-based Web applications Mix the DOM and JavaScript -- those perfect Ajax companions -- to change a Web page's user interface without page reloads Document options Print this page E-mail this page Document options requiring JavaScript are not displayed Sample code

Level: Intermediate Brett McLaughlin (brett@newInstance.com), Author and Rate this page Editor, O'Reilly Media Inc. 12 Sep 2006 Help us Combine the Document Object Model (DOM) with improve this JavaScript code to create interactive Ajax applications. content In previous articles in this series, you examined the concepts involved in DOM programming -- how the Web browser views a Web page as a tree -- and you should now understand the programming structures used in the DOM. In this article, you put all of this knowledge into practice and build a simple Web page that has some nice effects, all created using JavaScript to manipulate the DOM, without ever reloading or refreshing the page. You've had two full articles of introduction to the Document Object Model, or DOM; you should be pretty comfortable with how the DOM works by now. (See Resources for links to the first two DOM articles, as well as to earlier articles in the Ajax series.) In this article, you'll put that understanding into practice. You'll develop a basic Web application with a user interface that changes based on user actions -- of course, you'll use the DOM to handle changing that interface. By the time you're finished with this article, you'll have put most of the techniques and concepts you've learned about the DOM into practice. I assume that you've followed along for the last two articles; if you haven't, review them to get a solid understanding of the DOM and of how Web browsers turn the HTML and CSS you supply them into a single tree structure that represents a Web page. All of the DOM principles that I've talked about so far will be used in this article to build a working -- albeit somewhat simple -DOM-based dynamic Web page. If at any point in this article you get stuck, you can simply stop and review the earlier two articles, and come back. Getting started with the sample application Let's start out by putting together a very A note on the code basic application, and then adding a little To keep the focus specifically on DOM magic. In keeping with the idea that the DOM and JavaScript code, the DOM can move things around on a I've been somewhat sloppy and Web page without submitting a form -have written HTML with inline thus making it a perfect companion for style (like the align attribute on Ajax -- let's build a simple page that the h1 and p elements, for shows nothing but a plain old top hat, and example). While this is a button labeled Hocus Pocus! (Can you acceptable for trying things out, guess where this will go?) I recommend that you take the The initial HTML time to put all your styles into Listing 1 shows the HTML for this page; external CSS stylesheets for any it's just a body with a heading and a form, production applications you along with a simple image and a button develop. that you can push. Listing 1. The HTML for the sample application <html>

<head> <title>Magic Hat</title> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center"> <img src="topHat.gif" /> <br /><br /> <input type="button" value="Hocus Pocus!" /> </p> </form> </body> </html> You can find this HTML, along with all the images used in this article, available in Downloads at the end of this article. However, I highly recommend that you download just the images and then, as I build up the application throughout the article, type in the HTML by hand as you walk through the sample. You'll get a much better understanding of the DOM code in this way than you might by just reading the article and then simply opening up the completed application. Viewing the sample Web page Nothing particularly tricky here; open up the page and you should see something like Figure 1. Figure 1. A rather boring-looking top hat

A final point about the HTML One important point that you should note, though, is that the button on the form in Listing 1 and Figure 1 is of type button, and is not a submit button. If you do use a submit button, pressing the button will cause the browser to try and submit the form; of course, the form has no action attribute (which is entirely intentional), so this would just create an infinite loop of no activity. (You should try this on your own to see what happens.) By using a normal input button -- and avoiding the submit button -- you can connect a JavaScript function to the button and interact with the browser without submitting the form.

Back to top Adding more to the sample application Now, spruce up the Web page with some JavaScript, DOM manipulatin, and a little image wizardry. Using the getElementById() function Obviously, a magic hat isn't worth much without a rabbit. In this case, begin by replacing the image in the existing page (refer back to Figure 1) with an image of a rabbit, like that shown in Figure 2. Figure 2. The same top hat, this time with a rabbit

The first step in making this bit of DOM trickery occur involves looking up the

DOM node that represents the img element in the Web page. Generally, the easiest way to do this is to use the getElementById() method, available on the document object that represents the Web page. You've seen this method before; it functions like this: var elementNode = document.getElementById("id-of-element"); Adding an id attribute to the HTML This is pretty basic JavaScript, but it requires a bit of work in your HTML: the addition of an id attribute to the element that you want to access. That's the img element you want to replace (with a new image containing the rabbit); so you need to change our HTML to look like Listing 2. Listing 2. Adding an id attribute <html> <head> <title>Magic Hat</title> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center"> <img src="topHat.gif" id="topHat" /> <br /><br /> <input type="button" value="Hocus Pocus!" /> </p> </form> </body> </html> If you reload (or reopen) the page, you'll see nothing different at all; the addition of an id attribute has no visual effect on a Web page. It does, however, make it possible to work with an element more easily using JavaScript and the DOM. Grabbing the img element Now you can use getElementById() easily. You have the ID of the element you want -- topHat -- and can store that in a new JavaScript variable. Add in the code shown in Listing 3 to your HTML page. Listing 3. Getting access to the img element <html> <head> <title>Magic Hat</title> <script language="JavaScript">

function showRabbit() { var hatImage = document.getElementById("topHat"); } </script> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center"> <img src="topHat.gif" id="topHat" /> <br /><br /> <input type="button" value="Hocus Pocus!" /> </p> </form> </body> </html> Again, loading or reloading the Web page at this point won't show anything exciting. Even though you now have access to the image, you haven't done anything with it.

Back to top Changing the image, the hard way You can make the change you want in two ways: the hard way and the easy way. Like all good programmers, I typically prefer the easy way; however, walking through the longer path is a great DOM exercise, and well worth your time. Look at how to change out the image the hard way first; later, you'll reexamine things to see how to make the same change in an easier way. Here's what you need to do to replace the existing image with the newer, rabbit-inclusive image: 1. Create a new img element. 2. Get access to the element that is the parent -- that is, the container -of the current img element. 3. Insert the new img element as a child of the container just before the existing img element. 4. Remove the old img element. 5. Set things up so that the JavaScript function you've created is called when a user clicks the Hocus Pocus! button. Creating a new img element You should remember from my last two articles that the key to almost everything in the DOM is the document object. It represents an entire Web page, allows you access to powerful methods like getElementById(), and also

allows you to create new nodes. It's this last property you want to use now. Specifically, you need to create a new img element. Remember, in the DOM, everything is a node, but nodes are broken up further into three basic groups:
y y y

Elements Attributes Text nodes

There are other groups, but these three will serve you for about 99 percent of your programming needs. In this case,you want a new element, of type img. So you need this code in your JavaScript: var newImage = document.createElement("img"); This will create a new node, of type element, with the element name img. In HTML, that's essentially this: <img /> Remember, the DOM will create well-formed HTML, meaning that the element is currently empty, with both a starting and ending tag. All that's left is to add content or attributes to this element, and then insert it into the Web page. As for content, the img element is an empty element. However, you do need to add an attribute: the src attribute, which specifies the image to load. You might think that you need to use a method like addAttribute() here, but you would be incorrect. The DOM specification creators figured that as programmers, we might like a little shortcut (and we do!), so they created a single method to both add new attributes and change the value of existing ones: setAttribute(). If you call setAttribute() and supply an existing attribute, its value is changed to the value you supply. However, if you call setAttribute() and supply an attribute that does not exist, the DOM quietly adds the attribute, using the value you provide. One method, two purposes! So you need to add the following to your JavaScript: var newImage = document.createElement("img"); newImage.setAttribute("src", "rabbit-hat.gif");

This creates the image, and sets its source up appropriately. At this point, your HTML should look like Listing 4. Listing 4. Creating a new image using the DOM <html> <head> <title>Magic Hat</title> <script language="JavaScript">

function showRabbit() { var hatImage = document.getElementById("topHat"); var newImage = document.createElement("img"); newImage.setAttribute("src", "rabbit-hat.gif"); } </script> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center"> <img src="topHat.gif" id="topHat" /> <br /><br /> <input type="button" value="Hocus Pocus!" /> </p> </form> </body> </html> You can load this page, but don't expect any action; you haven't really done anything that affects the actual Web page yet. Plus, if you look back up at step 5 in the list of things to do, you might notice that your JavaScript function isn't even getting called yet! Getting the parent of the original image Now that you have an image ready to insert, you need somewhere to insert it. However, you're not inserting it into the existing image; instead, you want to put it before the existing image, and then remove the existing image. To do that, you need the parent of the existing image, which is really the key to all this inserting and removing. You should recall from the earlier articles that the DOM really sees a Web page as a tree, a hierarchy of nodes. Every node has a parent (a node higher up the tree that it is a child of), and possibly some children of its own. In the case of this image, there are no children -- remember, images are empty elements -but there is certainly a parent. You don't even care what the parent is; you just need to access it. To do that, you can just use the parentNode property that every DOM node has, like this: var imgParent = hatImage.parentNode; It's really that simple! You know that the parent can have children, because it already has one: the old image. Beyond that, you really don't need to know if the parent is a div, or a p, or even the body of the page; it just doesn't matter! Inserting the new image Now that you have the parent of the old image, you can insert the new image. That's fairly easy, as you can use several methods to add a child:

y y

insertBefore(newNode, oldNode) appendChild(newNode)

Since you want the new image to appear exactly where the old image is, you need insertBefore() (andyou'll also need to use the removeChild() method as well). Here's the line of JavaScript you'll use to insert the new image element just before the existing image: var imgParent = hatImage.parentNode; imgParent.insertBefore(newImage, hatImage);

At this point, the parent of the old image has two child images: the new image, immediately followed by the old image. It's important to note here that the content around these images is unchanged, and that the order of that content is exactly the same as it was before the insertion. It's just that the parent now has one additional child -- the new image -- directly before the old image. Removing the old image Now all that you need to do is remove the old image; you only want the new image in the Web page. This is simple, as you already have the old image element's parent. You can just call removeChild() and pass in the node you want to remove, like this: var imgParent = hatImage.parentNode; imgParent.insertBefore(newImage, hatImage); imgParent.removeChild(hatImage);

At this point, you essentially replaced the old image with the new one. Your HTML should look like Listing 5. Listing 5. Replacing the old image with the new <html> <head> <title>Magic Hat</title> <script language="JavaScript"> function showRabbit() { var hatImage = document.getElementById("topHat"); var newImage = document.createElement("img"); newImage.setAttribute("src", "rabbit-hat.gif"); var imgParent = hatImage.parentNode; imgParent.insertBefore(newImage, hatImage); imgParent.removeChild(hatImage); }

</script> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center"> <img src="topHat.gif" id="topHat" /> <br /><br /> <input type="button" value="Hocus Pocus!" /> </p> </form> </body> </html> Connecting the JavaScript The last step -- and perhaps the easiest -- is to connect your HTML form to the JavaScript function you just wrote. You want the showRabbit() function to run every time a user clicks the Hocus Pocus! button. To accomplish this, just add a simple onClick event handler to your HTML: <input type="button" value="Hocus Pocus!" onClick="showRabbit();" />

At this point in your JavaScript programming, this should be pretty routine. Add this into your HTML page, save the page, and then load the page into your Web browser. The page should initially look like Figure 1; click Hocus Pocus!, though, and you should get a result that looks like Figure 3. Figure 3. The rabbit has come out to play

Back to top Changing the image, the slightly easier way If you look back over the steps you took to change out the image, and then review the various methods available on nodes, you might notice a method called replaceNode(). This allows you to replace one node with another. Consider again the steps you took: 1. Create a new img element. 2. Get access to the element that is the parent -- that is, the container -of the current img element. 3. Insert the new img element as a child of the container just before the

existing img element. 4. Remove the old img element. 5. Set things up so that the JavaScript function you've created is called when a user clicks Hocus Pocus!. With replaceNode(), you can now reduce the number of stepsyou need to take. You can combine steps 3 and 4 so the process looks like this: 1. Create a new img element. 2. Get access to the element that is the parent -- that is, the container -of the current img element. 3. Replace the old img element with the new one you just created. 4. Set things up so that the JavaScript function you created is called when a user clicks Hocus Pocus!. This may not seem like a huge deal, but it certainly simplifies your code. Listing 6 shows how you can make this change: by removing the insertBefore() and removeChild() method calls. Listing 6. Replacing the old image with the new (in one step) <html> <head> <title>Magic Hat</title> <script language="JavaScript"> function showRabbit() { var hatImage = document.getElementById("topHat"); var newImage = document.createElement("img"); newImage.setAttribute("src", "rabbit-hat.gif"); var imgParent = hatImage.parentNode; imgParent.replaceChild(newImage, hatImage); } </script> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center"> <img src="topHat.gif" id="topHat" /> <br /><br /> <input type="button" value="Hocus Pocus!" onClick="showRabbit();" /> </p> </form> </body> </html> Again, this isn't a big change, but it does illustrate a rather important point in

DOM coding: you can usually find a few ways to perform any given task. Many times, you can cut what takes four or five steps down to two or three if you carefully review the DOM methods available to you, and see if there are perhaps shorter ways to accomplish a task.

Back to top Changing the image, the (really) easy way Since I've pointed out that there is almost always an easier way to perform a task, I'll now show you that there's a much easier way to replace the top hat image with the rabbit image. Did you figure out what that approach is as you worked through this article? Here's a hint: it has to do with attributes. Remember, the image element is largely controlled by its src attribute, which refers to a file somewhere (either a local URI or an external URL). So far, you've replaced the image node with a new image; however, it's much simpler to just change the src attribute of the existing image! This consolidates all the work of creating a new node, finding the parent, and replacing the old node into a single step: hatImage.setAttribute("src", "rabbit-hat.gif"); That's all it takes! Look at Listing 7, which shows this solution in the context of an entire Web page. Listing 7. Changing the src attribute <html> <head> <title>Magic Hat</title> <script language="JavaScript"> function showRabbit() { var hatImage = document.getElementById("topHat"); hatImage.setAttribute("src", "rabbit-hat.gif"); } </script> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center"> <img src="topHat.gif" id="topHat" /> <br /><br /> <input type="button" value="Hocus Pocus!" onClick="showRabbit();" /> </p> </form> </body>

</html> This is one of the coolest thing about the DOM: when you update an attribute, the Web page immediately changes. As soon as the image points to a new file, the browser loads that file, and the page is updated. No reloading is necessary, and you don't even need to create a new image element! The result is still identical to Figure 3, shown above -- it's just that the code is far simpler.

Back to top Hiding that rabbit Currently, the Web page is pretty nifty, but still a bit primitive. Even though the rabbit pops out of the hat, the button on the bottom of the screen still reads Hocus Pocus! once he's out, and still calls showRabbit(). This means that if you click on the button after the rabbit is revealed, you waste processing time. More importantly, it's just plain useless, and useless buttons are never a good thing. Let's see if you can use the DOM to make a few more changes, and make that button useful whether the rabbit is in the hat or out of it. Changing the button's label The easiest thing to do is to change the label of the button after a user clicks it. That way, it doesn't seem to indicate that anything else magical will occur; the worst thing a Web page can do is imply something to the user that's not correct. Before you can change the button's label, though, you need to get access to the node; and before you can do that, you need an ID to reference the button by. This should be old hat by now, right? Listing 8 adds an id attribute to the button. Listing 8. Adding an id attribute <html> <head> <title>Magic Hat</title> <script language="JavaScript"> function showRabbit() { var hatImage = document.getElementById("topHat"); hatImage.setAttribute("src", "rabbit-hat.gif"); } </script> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center"> <img src="topHat.gif" id="topHat" /> <br /><br />

<input type="button" value="Hocus Pocus!" onClick="showRabbit();" /> </p> </form> </body> </html> Now it's trivial to access the button in your JavaScript:

id="hocusPocus"

function showRabbit() { var hatImage = document.getElementById("topHat"); hatImage.setAttribute("src", "rabbit-hat.gif"); var button = document.getElementById("hocusPocus"); } Of course, you probably already typed in the next line of JavaScript, to change the value of the button's label. Again, setAttribute() comes into play: function showRabbit() { var hatImage = document.getElementById("topHat"); hatImage.setAttribute("src", "rabbit-hat.gif"); var button = document.getElementById("hocusPocus"); button.setAttribute("value", "Get back in that hat!"); } With this simple bit of DOM manipulation, the button's label will change as soon as the rabbit pops out. At this point, your HTML and completed showRabbit() function should look like Listing 9. Listing 9. The completed (for now) Web page <html> <head> <title>Magic Hat</title> <script language="JavaScript"> function showRabbit() { var hatImage = document.getElementById("topHat"); hatImage.setAttribute("src", "rabbit-hat.gif"); button.setAttribute("value", "Get back in that hat!"); } </script> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center">

<img src="topHat.gif" id="topHat" /> <br /><br /> <input type="button" value="Hocus Pocus!" id="hocusPocus" onClick="showRabbit();" /> </p> </form> </body> </html> Putting the rabbit back As you might guess from the new button label, it's time to get the rabbit back into the hat. This essentially just reverses the process by which you got him out: changing the image's src attribute back to the old image. Create a new JavaScript function to do this: function hideRabbit() { var hatImage = document.getElementById("topHat"); hatImage.setAttribute("src", "topHat.gif"); var button = document.getElementById("hocusPocus"); button.setAttribute("value", "Hocus Pocus!"); } This is really just a matter of reversing everything that the showRabbit() function does. Set the image to the old, rabbit-free top hat, grab the button, and change its label back to Hocus Pocus!

Back to top Dealing with event handlers The sample application at this point has one big problem: even though the label of the button changes, the action that occurs when you click that button does not. Fortunately, you can change the event -- the action that occurs -when a user clicks the button using the DOM. So if the button reads Get back in that hat!, you want it to run hideRabbit() when it's clicked. Conversely, once the rabbit is hidden, the button returns to running showRabbit(). Avoid addEventHandler() In addition to the onclick property, there's a method intended to be used to add an event handler, like onClick or onBlur; it's unsurprisingly called addEventHandler(). Unfortunately, MicrosoftΠInternet ExplorerΠdoesn't support this method, so if you use it in your JavaScript, millions of Internet Explorer users are going to get nothing

If you look at the HTML, you'll see that the from your page other than an event you deal with here is onClick. In error (and probably some ideas JavaScript, you can reference this event about complaints). Avoid this using the onclick property of a button. method; you can get the same (Note that in HTML, the property is results with the approach in this generally referred to as onClick, with a article, which does work on capital C, and in JavaScript, it's onclick, all Internet Explorer. lowercase.) So you can change the event that's run on a button: you just assign a new function to the onclick property. But there's a slight twist: the onclick property wants to be fed a function reference -- not the string name of a function, but a reference to the function itself. In JavaScript, you can reference a function by its name, without any parentheses. So you might change the function that runs when a button is clicked like this: button.onclick = myFunction; In your HTML, then, making this change is pretty simple. Check out Listing 10, which toggles the functions that the button runs. Listing 10. Changing the button's onClick function <html> <head> <title>Magic Hat</title> <script language="JavaScript"> function showRabbit() { var hatImage = document.getElementById("topHat"); hatImage.setAttribute("src", "rabbit-hat.gif"); var button = document.getElementById("hocusPocus"); button.setAttribute("value", "Get back in that hat!"); button.onclick = hideRabbit; } function hideRabbit() { var hatImage = document.getElementById("topHat"); hatImage.setAttribute("src", "topHat.gif"); var button = document.getElementById("hocusPocus"); button.setAttribute("value", "Hocus Pocus!"); button.onclick = showRabbit; } </script> </head> <body> <h1 align="center">Welcome to the DOM Magic Shop!</h1> <form name="magic-hat"> <p align="center"> <img src="topHat.gif" id="topHat" />

<br /><br /> <input type="button" value="Hocus Pocus!" onClick="showRabbit();" /> </p> </form> </body> </html> This is a complete, ready-to-use DOM application. Try it out and see for yourself! id="hocusPocus"

Back to top In conclusion At this point, you should be pretty comfortable with the DOM. In previous articles, you saw the basic concepts involved in working with the DOM, and got a detailed look at the API; now you've worked through a simple DOM-based application. Be sure to take your time with this article, and try it out online for yourself. Although this is the last of the articles in this series specifically focusing on the Document Object Model, it's not the last you'll see of the DOM. In fact, you'll be hard-pressed to do much in the Ajax and JavaScript worlds without using the DOM to at least some degree. Whether you create complex highlighting and movement effects, or just work with text blocks or images, the DOM gives you access to a Web page in a really easy-to-use manner. If you still feel a little unsure of how to use the DOM on your own, take some time to revisit this set of three articles; the rest of this series will use the DOM without much explanation, and you don't want to get lost in those details and miss out on important information about other concepts, such as XML or JSON. Be sure you're comfortable using the DOM, write a few DOM-based applications on your own, and you'll be ready to tackle some of the data format issues I'll be discussing over the next several months.

Downloads Description Example graphics only Complete example, including Name wa-ajaxintro6/ajax_6-images_download.zip Size Download method

91 KB HTTP

wa-ajaxintro6/ajax_6-complete_examples.zip 93 KB HTTP

HTML and graphics Information about download methods

Mastering Ajax, Part 7: Using XML in requests and responses Learn when it's a good idea -- and when it isn't Level: Intermediate Document options Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc. Print this 10 Oct 2006 page Even casual Ajax developers will notice the x in Ajax, E-mail this and realize that it stands for XML. XML is one of the page most popular data formats in any programming medium, Document and offers real advantages for server responses in options asynchronous applications. In this article, you'll see how requiring servers can send XML in response to a request. JavaScript You really can't do any significant programming today are not without running across XML. Whether you're a Web page displayed designer considering the move to XHTML, a Web programmer working with JavaScript, a server-side Rate this page programmer using deployment descriptors and data binding, or a back-end developer investigating XMLbased databases, the extensible markup language is everywhere. It's no surprise, then, that XML is considered one of the core technologies that underlies Ajax. However, this opinion reflects the poor choice of names for the core object used in Ajax applications -- XMLHttpRequest -- more than it does technical reality. In other words, most people think XML is a core part of Ajax because they assume that the XMLHttpRequest object actually uses XML all the time. But that's not the case, and the reasons why are the subject of the first part of this article. In fact, you'll see that in most Ajax applications, XML rarely makes an appearance at all. XML does have real uses in Ajax, and XMLHttpRequest allows for these as well. There's certainly nothing keeping you from sending XML to a server. In earlier articles in this series, you used plain text and name/value parameters to send data, but XML is also a viable format. In this article, you'll look at how to do that. More importantly, though, I'll talk about why you might use XML for your request format, and why, in many cases, you shouldn't use it. XML: Is it really there at all? It's easy to make assumptions about Ajax applications and their usage of XML; both the technology name (Ajax) and the core object it uses (XMLHttpRequest) imply the use of XML, and you'll hear XML linked with Ajax applications all the

time. However, this perception is simply wrong, and if you want to really know your stuff when it comes to writing asynchronous applications, you need to know that the perception is wrong -- and, better yet, know why it's wrong. XMLHttpRequest: Poor names and HTTP One of the worst things that can happen to a technology is for it to become so hot that changing basic pieces of it becomes impossible. That's exactly what's happened with XMLHttpRequest, the basic object used in Ajax apps. It sounds like it's designed to either send XML over HTTP requests, or perhaps make HTTP requests in some sort of XML format. Whatever the object's name sounds like, though, what it actually does is simply provide a way for your client code (usually JavaScript in your Web page) to send an HTTP request. That's it; there's really nothing more to it. Thus, it would be nice to simply change XMLHttpRequest's name to something more accurate, like HttpRequest, or perhaps simply Request. However, millions of developers are now throwing Ajax into their applications, and because we all know that it takes years -- if not decades -- for the majority of users to move to new browser versions like Internet Explorer 7.0 or Firefox 1.5, such a move is simply not feasible. The end result is that you're stuck with XMLHttpRequest, and it's up to developers to realize that the thing is just poorly named. It's somewhat telling that one of the best known fallback methods for dealing with a browser (especially on Windows) that doesn't support XMLHttpRequest is to use the Microsoft IFRAME object. Hardly sounds like XML, HTTP, or even a request, does it? Obviously, all those things might be involved, but this should simply make clear the fact that the XMLHttpRequest object is a lot more about making requests without requiring a page reload than it is about XML, or even HTTP. The requests are HTTP, not XML Another common mistake is to suppose that XML is somehow used behind the scenes -- a view I once held myself, to be honest! However, that view reflects a poor understanding of the technology. When a user opens a browser and requests a Web page from a server, they type in something like http://www.google.com or http://www.headfirstlabs.com. Even if they don't include the http://, the browser will fill in that part in the browser address bar. That first part -- http:// -- is a not-so-subtle clue about how communication is occurring: through HTTP, the Hypertext Transfer Protocol. When you write code in your Web page to communicate with a server, whether it's using Ajax or a normal form POST or even a hyperlink, you're just talking HTTP. HTTPS: Still HTTP Those of you newer to the Web might wonder about URLs like https://intranet.nextel.com. The https is secure HTTP, and just uses a more secure form of the HTTP protocol used by ordinary Web requests. So even with HTTPS, you're still just talking HTTP, albeit with

Given that pretty much all Web some extra layers of communication between browsers and servers security added to keep takes place through HTTP, the idea that XML is away prying eyes. somehow the transport or technology used by XMLHttpRequest under the covers just doesn't make any sense. It's certainly possible for XML to be sent in the HTTP request, but HTTP is a very precisely defined standard that isn't going away any time soon. Unless you're specifically using XML in your request, or the server is sending you a response in XML, there's nothing but plain old HTTP used in the XMLHttpRequest object. So the next time someone tells you, "Yeah, it's called XMLHttpRequest because it uses XML behind the scenes," just smile and patiently explain to them what HTTP is, and let them know that while XML can be sent over HTTP, XML is a data format, not a transfer protocol. You'll both be the better for the explanation.

Using XML (for real) So far, I've told you about all the places where XML isn't used in Ajax. But the x in Ajax and the XML in XMLHttpRequest are still very real, and you've several options for using XML in your Web applications. You'll look at the basic options in this section, and then really dig into detail in the rest of this article. Options for XML In your asynchronous apps, you'll find two basic applications of XML:
y y

To send a request from a Web page to a server in XML format To receive a request from a server in your Web page in XML format

The first of these -- to send a request in XML -- requires you to format your request as XML, either using an API to do so or just stringing together the text, and then sending the result to a server. In this option, the main job at hand is to construct the request in a way that complies with the rules of XML, and that can be understood by the server. So the focus is really on the XML format; you have the data you want to send, and just need to wrap it up in XML semantics. The rest of this article focuses on this use of XML in your Ajax applications. The second of these options -- to receive a request in XML -- requires you to take a response from a server, and extract the data from XML (again, using either an API or more of a brute force approach). In this case, your focus is on the data from the server, and it just so happens that you've got to pull that data out of XML to use it in any constructive way. This is the subject of the next article in this series, and you'll really dig into that in detail then. A preemptory warning Before I get into the details of using XML, a short cautionary word is in order: XML is not a small, fast, space-saving format. As you'll see in the next several sections and in the next article in this series, there are some great reasons to use XML in this context, and some advantages that XML has over plain text requests and responses (especially for responses). However, XML is almost

always going to take up more space and be slower than plain text, because you add all the tags and semantics required for XML to your messages. If you want to write a blazing fast application that feels like a desktop app, XML might not be the best place to start. If you begin with plain text, and find a specific need for XML, then that's great; however, if you use XML from the beginning, you almost certainly slow down your application's responsiveness. In most cases, it's faster to send plain text -- using name/value pairs like name=jennifer -- than to turn the text into XML like this: <name>jennifer</name> Think of all the places where using XML adds time: wrapping the text in XML; sending across extra information (note that I didn't include any surrounding elements, an XML header, or anything else that would probably be part of a more realistic request); having the server parse the XML, generate a response, wrap the response back in XML, and send it back to your Web page; and then having your page parse the response and finally use it. So learn when to use XML, but don't start out by thinking that it's going to make your application faster in many situations; rather, it adds flexibility, as we'll begin to talk about now.

XML from the client to the server Let's look at using XML as the format to send data from a client to a server. First, you'll see how to do this technically, and then spend some time examining when this is a good idea, and when it's not. Sending name/value pairs In about 90 percent of the Web apps you write, you'll end up with name/value pairs to send to a server. For example, if a user types their name and address into a form on your Web page, you might have data like this from the form: firstName=Larry lastName=Gullahorn street=9018 Heatherhorn Drive city=Rowlett state=Texas zipCode=75080 If you were just using plain text to send this data to a server, you might use code that looks something like Listing 1. (This is similar to an example I used in the first article in this series. See Resources.) Listing 1. Sending name/value pairs in plain text function callServer() { // Get the city and state from the Web form var firstName = document.getElementById("firstName").value;

var var var var var

lastName = document.getElementById("lastName").value; street = document.getElementById("street").value; city = document.getElementById("city").value; state = document.getElementById("state").value; zipCode = document.getElementById("zipCode").value;

// Build the URL to connect to var url = "/scripts/saveAddress.php?firstName=" + escape(firstName) + "&lastName=" + escape(lastName) + "&street=" + escape(street) + "&city=" + escape(city) + "&state=" + escape(state) + "&zipCode=" + escape(zipCode); // Open a connection to the server xmlHttp.open("GET", url, true); // Set up a function for the server to run when it's done xmlHttp.onreadystatechange = confirmUpdate; // Send the request xmlHttp.send(null); } Converting name/value pairs to XML The first thing you need to do if you want to use XML as a format for data like this is to come up with some basic XML format in which to store the data. Obviously, your name/value pairs can all turn into XML elements, where the element name is the name of the pair, and the content of the element is the value: <firstName>Larry</firstName> <lastName>Gullahorn</lastName> <street>9018 Heatherhorn Drive</street> <city>Rowlett</city> <state>Texas</state> <zipCode>75080</zipCode> Of course, XML requires that you have a root element, or, if you're just working with a document fragment (a portion of an XML document), an enclosing element. So you might convert the XML above to something like this: <address> <firstName>Larry</firstName> <lastName>Gullahorn</lastName> <street>9018 Heatherhorn Drive</street> <city>Rowlett</city> <state>Texas</state> <zipCode>75080</zipCode>

</address> Now you're ready to create this structure in your Web client, and send it to the server ... almost. Communication, of the verbal kind Before you're ready to start tossing XML over the network, you want to make sure that the server -- and script -- to which you send data actually accepts XML. Now for many of you, this might seem like a silly and obvious point to make, but plenty of newer programmers just assume that if they send XML across the network, it is received and interpreted correctly. In fact, you need to take two steps to ensure that the data you send in XML will be received correctly: 1. Ensure that the script to which you send the XML accepts XML as a data format. 2. Ensure the script will accept the particular XML format and structure in which you send data. Both of these will probably require you to actually talk to a human being, so fair warning! Seriously, if it's important that you be able to send data as XML, most script writers will oblige you; so just finding a script that will accept XML shouldn't be that hard. However, you'still need to make sure that the your format matches what the script expects. For example, suppose the server accepts data like this: <profile> <firstName>Larry</firstName> <lastName>Gullahorn</lastName> <street>9018 Heatherhorn Drive</street> <city>Rowlett</city> <state>Texas</state> <zip-code>75080</zip-code> </profile> This looks similar to the XML above, except for two things: 1. The XML from the client is wrapped within an address element, but the server expects the data to be wrapped within a profile element. 2. The XML from the client uses a zipCode element, while the server expects the zip code to be in a zip-code element. In the grand scheme of things, these really small points are the difference between the server accepting and processing your data, and the server crashing miserably and supplying your Web page -- and probably its users -with a cryptic error message. So you've got to figure out what the server expects, and mesh the data you send into that format. Then -- and only then - are you ready to deal with the actual technicalities of sending XML from a client to a server.

Sending XML to the server When it comes to sending XML to the server, you'll spend more of your code taking your data and wrapping it XML than you will actually transmitting the data. In fact, once you have the XML string ready to send to the server, you send it exactly as you would send any other plain text; check out Listing 2 to see this in action. Listing 2. Sending name/value pairs in XML function callServer() { // Get the city and state from the Web form var firstName = document.getElementById("firstName").value; var lastName = document.getElementById("lastName").value; var street = document.getElementById("street").value; var city = document.getElementById("city").value; var state = document.getElementById("state").value; var zipCode = document.getElementById("zipCode").value; var xmlString = "<profile>" + " " " " " " <firstName>" + escape(firstName) + "</firstName>" + <lastName>" + escape(lastName) + "</lastName>" + <street>" + escape(street) + "</street>" + <city>" + escape(city) + "</city>" + <state>" + escape(state) + "</state>" + <zip-code>" + escape(zipCode) + "</zip-code>" +

"</profile>"; // Build the URL to connect to var url = "/scripts/saveAddress.php"; // Open a connection to the server xmlHttp.open( "POST" , url, true); // Tell the server you're sending it XML xmlHttp.setRequestHeader("Content-Type", "text/xml"); // Set up a function for the server to run when it's done xmlHttp.onreadystatechange = confirmUpdate; // Send the request xmlHttp.send(xmlString);

} Much of this is self-explanatory with just a few points worth noting. First, the data in your request must be manually formatted as XML. That's a bit of a letdown after three articles on using the Document Object Model, isn't it? And while nothing forbids you from using the DOM to create an XML document using JavaScript, you'd then have to convert that DOM object to text before sending it over the network with a GET or POST request. So it turns out to be easier to simply format the data using normal string manipulation. Of course, this introduces room for error and typographical mistakes, so you need to be extra careful when you write code that deals with XML. Once you construct your XML, you open a connection in largely the same way as you would when you send text. I tend to prefer using POST requests for XML, since some browsers impose a length limitation on GET query strings, and XML can get pretty long; you'll see that Listing 2 switches from GET to POST accordingly. Additionally, the XML is sent through the send() method, rather than as a parameter tacked on to the end of the URL you're requesting. These are all fairly trivial differences, though, and easy to adjust for. You will have to write one entirely new line of code, though: xmlHttp.setRequestHeader("Content-Type", "text/xml"); This isn't hard to understand: it just tells the server that you're sending it XML, rather than plain old name/value pairs. In either case, you send data as text, but use text/xml here, or XML sent as plain text. If you just used name/value pairs, this line would read: xmlHttp.setRequestHeader("Content-Type", "text/plain"); If you forget to tell the server that you're sending it XML, you'll have some trouble, so don't forget this step. Once you get all this put together, all you need to do is call send() and pass in the XML string. The server will get your XML request, and (assuming you've done your pre-work) accept the XML, parse it, and send you back a response. That's really all there is to it -- XML requests with just a few changes of code.

Sending XML: Good or bad? Before leaving XML requests (and this article) for XML responses, let's spend some real time thinking about the sensibility of using XML in your requests. I've already mentioned that XML is by no means the fastest data format in terms of transfer, but there's a lot more to think about. XML is not simple to construct The first thing you need to realize is that XML is just not that easy to construct for use in requests. As you saw in Listing 2, your data quickly becomes pretty convoluted with the semantics of XML:

var xmlString = "<profile>" + " <firstName>" + escape(firstName) + "</firstName>" + " <lastName>" + escape(lastName) + "</lastName>" + " <street>" + escape(street) + "</street>" + " <city>" + escape(city) + "</city>" + " <state>" + escape(state) + "</state>" + " <zip-code>" + escape(zipCode) + "</zip-code>" + "</profile>"; This might not seem so bad, but it's also an XML fragment that has only six fields. Most of the Web forms you'll develop will have ten to fifteen; although you won't use Ajax for all of your requests, it is a consideration. You're spending at least as much time dealing with angle brackets and tag names as you are with actual data, and the potential to make little typos is tremendous. Another problem here is that -- as already mentioned -- you will have to construct this XML by hand. Using the DOM isn't a good option, as there aren't good, simple ways to turn a DOM object into a string that you can send as a request. So working with strings like this is really the best option -- but it's also the option that's hardest to maintain, and hardest to understand for new developers. In this case, you constructed all the XML in one line; things only get more confusing when you do this in several steps. XML doesn't add anything to your requests Beyond the issue of complexity, using XML for your requests really doesn't offer you much of an advantage -- if any -- over plain text and name/value pairs. Consider that everything in this article has been focused on taking the same data you could already send using name/value pairs (refer back to Listing 1) and sending it using XML. At no point was anything said about data that you can send with XML that you could not send using plain text; that's because there almost never is anything that you can send using XML that you can't send using plain text. And that's really the bottom line with XML and requests: there's just rarely a compelling reason to do it. You'll see in the next article in this series that a server can use XML for some things that are much harder to do when using plain text; but it's just not the case with requests. So unless you're talking to a script that only accepts XML (and there are some out there), you're better off using plain text in almost every request situation.

In conclusion You should definitely feel like you're starting to get the XML in Ajax figured out. You know that Ajax apps don't have to use XML, and that XML isn't some sort of magic bullet for data transfer. You should also feel pretty comfortable in sending XML from a Web page to a server. Even more importantly, you know what's involved in making sure that a server will actually handle and respond to your requests: you've got to ensure that the server script accepts XML, and that it accepts it in the format that you're using to send the data over.

You also should have a good idea now of why XML isn't always that great a choice for a data format for requests. In future articles, you'll see some cases where it helps, but in most requests, it simply slows things down and adds complexity. So while I'd normally suggest that you immediately start using the things you learned in an article, I'll instead suggest that you be very careful about using what you've learned here. XML requests have their place in Ajax apps, but that place isn't as roomy as you might think. In the next article in this series, you'll look at how servers can respond using XML, and how your Web applications can handle those responses. Happily, there's a much larger number of reasons for a server to send XML back to a Web app than the other way around, so you'll get even more use out of that article's technical detail; for now, be sure you understand why XML isn't always a great idea -- at least for sending requests. You might even want to try and implement some Web apps using XML as the data format for requests, and then convert back to plain text, and see which seems both faster and easier to you. Until next article, I'll see you online.

Mastering Ajax, Part 8: Using XML in requests and responses Ajax client/server communication can be a tricky business

Level: Intermediate Document options Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc. Print this 07 Nov 2006 page In the last article of the series, you saw how your Ajax apps can E-mail this format requests to a server in XML. You also saw why, in most cases, page that isn't a good idea. This article focuses on something that often is Document a good idea: returning XML responses to a client. options I don't really enjoy writing articles that are primarily about requiring something that you shouldn't do. Most of the time, it's a pretty silly JavaScript type of thing to write. I spend half an article explaining something, are not just so I can spend the rest of the article explaining what a bad idea displayed it is to use the techniques you've just learned about. Such was the case, to a large degree, with last month's article (if you missed it, check out the link in Resources), which taught you how to use XML as Rate this page the data format for your Ajax apps' requests. Hopefully, this article will redeem the time you spent learning about XML requests. In Ajax apps, while there are very few reasons to use XML as the sending data format, there are a lot of reasons why you might want a server to send XML back from a server, to a client. So everything you learned about XML in the last article will definitely start to have some value in this article. Servers can't say much (sometimes) Before you dive into the technical details of getting an XML response from a server, you need to understand why it's such a good idea for a server to send XML in response to a request (and how that's different from a client sending that request in XML). Clients speak in name/value pairs As you'll recall from the last article, clients don't need to use XML in most cases because they can send requests using name/value pairs. So you might send a name like this: name=jennifer. You can stack those up by simply adding an ampersand (&) between successive name/value pairs, like this: name=jennifer&job=president. Using simple text and these name/value pairs, clients can send requests with multiple values to a server easily. There's rarely a need for the additional structure (and overhead) that XML provides. In fact, almost all the reasons you'd need to send XML to a server can be grouped into two basic categories:
y

y

The server only accepts XML requests. In these cases, you don't have a choice. The basics in last month's article should give you all the tools you need to send these sorts of requests. You're calling a remote API that only accepts XML or SOAP requests. This is really just a specialized case of the previous point, but it's worth mentioning on its own. If you want to use the APIs from Google or Amazon in an asynchronous request, there are some particular considerations. I'll look at those, and a few examples of making requests to APIs like this, in next month's article.

Servers can't send name/value pairs (in a standard way) When you send name/value pairs, the Web browser sending the requests and the platform responding to that request and hosting a server program cooperate to turn those name/value pairs into data that a server program can work with easily. Practically every server-side technology -- from JavaΠservlets to PHP to Perl to Ruby on Rails -- allows you

to call a variety of methods to get at values based on a name. So getting the name attribute is trivial. This isn't the case going in the other direction. If a server replied to an app with the string name=jennifer&job=president, the client has no standardized, easy way to break up the two name/value pairs, and then break each pair into a name and value. You'll have to parse the returned data manually. If a server returns a response made up of name/value pairs, that response is no easier (or harder) to interpret than a response with elements separated by semicolons, or pipe symbols, or any other nonstandard formatting character. What that leaves you with, then, is no easy way to Give me some space! use plain text in your responses and have the client In most HTTP requests, the get that response and interpret it in a standard way, escape sequence %20 is used to at least when the response contains multiple values. If represent a single space. So the your server simply sent back the number 42, say, text "Live Together, Die Alone" is plain text would be great. But what about if it's sent over HTTP as sending back the latest ratings for the TV shows Lost, Live%20Together,%20Die%20Alone. Alias, and Six Degrees, all at once? While you can chose many ways to send this response using plain text (see Listing 1 for a few examples), none are particularly easy to interpret without some work by the client, and none are standardized at all. Listing 1. Server response for TV ratings (various versions) show=Alias&ratings=6.5|show=Lost&ratings=14.2|show=Six%20Degrees&ratings=9.1 Alias=6.5&Lost=14.2&Six%20Degrees=9.1 Alias|6.5|Lost|14.2|Six%20Degrees|9.1 Even though it's not too hard to figure out how to break up these response strings, a client will have to parse and split the string up based on the semicolons, equal signs, pipes, and ampersands. This is hardly the way to write robust code that other developers can easily understand and maintain. Enter XML When you realize that there's no standard way for a server to respond to clients with name/value pairs, the reasoning behind using XML becomes pretty clear. When sending data to the server, name/value pairs are a great choice because servers and server-side languages can easily interpret the pairs; the same is true for using XML when returning data to a client. You saw the use of the DOM to parse XML in several earlier articles, and will see how JSON provides yet another option to parse XML in a future article. And on top of all that, you can treat XML as plain text, and get values out of it that way. So there are several ways to take an XML response from a server, and, with fairly standard code, pull the data out and use it in a client. As an added bonus, XML is generally pretty easy to understand. Most people who program can make sense of the data in Listing 2, for example. Listing 2. Server response for TV ratings (in XML)

<ratings> <show> <title>Alias</title> <rating>6.5</rating> </show> <show> <title>Lost</title> <rating>14.2</rating> </show> <show> <title>Six Degrees</title> <rating>9.1</rating> </show> </ratings> The code in Listing 2 has no mystery about what a particular semicolon or apostrophe means.

Receiving XML from a server Because the focus of this series is on the client side of the Ajax equation, I won't delve into much detail about how a server-side program can generate a response in XML. However, you need to know about some special considerations when your client receives XML. First, you can treat an XML response from a server in two basic ways:
y y

As plain text that just happens to be formatted as XML As an XML document, represented by a DOM Document object.

Second, presume a simple response XML from a server for example's sake. Listing 3 shows the same TV listings as detailed above (this is, in fact, the same XML as in Listing 2, reprinted for your convenience). I'll use this sample XML in the discussions in this section. Listing 3. XML-formatted TV ratings for examples

<ratings> <show> <title>Alias</title> <rating>6.5</rating> </show> <show> <title>Lost</title> <rating>14.2</rating> </show> <show> <title>Six Degrees</title> <rating>9.1</rating>

</show> </ratings> Dealing with XML as plain text The easiest option to handle XML, at least in terms of learning new programming techniques, is to treat it like any other piece of text returned from a server. In other words, you basically ignore the data format, and just grab the response from the server. In this situation, you use the responseText property of your request object, just as you would when the server sends you a non-XML response (see Listing 4). Listing 4. Treating XML as a normal server response function updatePage() { if (request.readyState == 4) { if (request.status == 200) { var response = request.responseText; // response has the XML response from the server alert(response); } } } In this code fragment, updatePage() is the callback, and request is the XMLHttpRequest object. You end up with the XML response, all strung together, in the response variable. If you printed out that variable, you'd have something like Listing 5. (Note that the code in Listing 5 normally is one, continuous line. Here, it is shown on multiple lines for display purposes.) Listing 5. Value of response variable <ratings><show><title>Alias</title><rating>6.5</rating> </show><show><title>Lost</title><rating>14.2</rating></show><show> <title>Six Degrees</title><rating>9.1</rating></show></ratings> The most important thing to note here is that the XML is all run together. In most cases, servers will not format XML with spaces and carriage returns; they'll just string it all together, like you see in Listing 5. Of course, your apps don't care much about spacing, so this is no problem; it does make it a bit harder to read, though. At this point, you can use the JavaScript split function to break up this data, and basic string manipulation to get at the element names and their values. Of course, that's a pretty big

Review earlier articles To avoid lots of repetitive code, these later articles in the series only show the portions of code relevant to the subject being discussed. So Listing 4 only shows the callback method in your Ajax client's code. If you're unclear on how this method fits into the larger context of an asynchronous app, you should review the first several articles in the series, which cover the fundamentals of Ajax apps. See Resources for links to those earlier articles.

pain, and it ignores the handy fact that you spent a lot of time looking at the DOM, the Document Object Model, earlier in this series. So I'll urge you to keep in mind that you can use and output a server's XML response easily using responseText, but I wont show you much more code; you shouldn't use this approach to get at the XML data when you can use the DOM, as you'll see next. Treating XML as XML While you can treat a server's XML-formatted response like any other textual response, there's no good reason to do so. First, if you've read this series faithfully, you know how to use the DOM, a JavaScript-friendly API with which you can manipulate XML. Better yet, JavaScript and the XMLHttpRequest object provide a property that is perfect for getting the server's XML response, and getting it in the form of a DOM Document object. To see this in action, check out Listing 6. This code is similar to Listing 4, but rather than use the responseText property, the callback uses the responseXML property instead. This property, available on XMLHttpRequest, returns the server's response in the form of a DOM document. Listing 6. Treating XML as XML function updatePage() { if (request.readyState == 4) { if (request.status == 200) { var xmlDoc = request.responseXML; // work with xmlDoc using the DOM } } } Now you have a DOM Document, and you can work with it just like any other XML. For example, you might then grab all the show elements, as in Listing 7. Listing 7. Grabbing all the show elements function updatePage() { if (request.readyState == 4) { if (request.status == 200) { var xmlDoc = request.responseXML; var showElements = xmlDoc.getElementsByTagName("show"); } } } If you're familiar with DOM, this should start to feel familiar. You can use all the DOM methods you've already learned about, and easily manipulate the XML you received from the server. You can also, of course, mix in normal JavaScript code. For instance, you might iterate

through all the show elements, as in Listing 8. Listing 8. Iterating through all the show elements function updatePage() { if (request.readyState == 4) { if (request.status == 200) { var xmlDoc = request.responseXML; var showElements = xmlDoc.getElementsByTagName("show"); for (var x=0; x<showElements.length; x++) { // We know that the first child of show is title, and the second is rating var title = showElements[x].childNodes[0].value; var rating = showElements[x].childNodes[1].value; // Now do whatever you want with the show title and ratings } } } } With this relatively simple code, you treated an XML response like it's XML, not just plain unformatted text, and used a little DOM and some simple JavaScript to deal with a server's response. Even more importantly, you worked with a standardized format -- XML -- instead of comma-separated values or pipe-delimited name/value pairs. In other words, you used XML where it made sense, and avoided it when it didn't, like in sending requests to the server. XML on the server: A brief example Although I haven't talked much about how to generate XML on the server, it's worth seeing a brief example, without much commentary, just so you can come up with your own ideas on how to deal with such a situation. Listing 9 shows a simple PHP script that outputs XML in response to a request, presumably from an asynchronous client. This is the brute force approach, where the PHP script is really just pounding out the XML output manually. You can find a variety of toolkits and APIs for PHP and most other serverside languages that also allow you to generate XML responses. In any case, this at least gives you an idea of what server-side scripts that generate and reply to requests with XML look like. Listing 8. PHP script that returns XML <?php // Connect to a MySQL database

$conn = @mysql_connect("mysql.myhost.com", "username", "secret-password"); if (!conn) die("Error connecting to database: " . mysql_error()); if (!mysql_select_db("television", $conn)) die("Error selecting TV database: " . mysql_error()); // Get ratings for all TV shows in database $select = 'SELECT title, rating'; $from = ' FROM ratings'; $queryResult = @mysql_query($select . $from); if (!$queryResult) die("Error retrieving ratings for TV shows.'); // Let the client know we're sending back XML header("Content-Type: text/xml"); echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>"; echo "<ratings>"; while ($row = mysql_fetch_array($queryResult)) { $title = $row['title']; $rating = $row['rating']; echo echo echo echo } echo "</ratings>"; mysql_close($conn); ?> You should be able to output XML in a similar way using your own favorite server-side language. A number of articles on IBM developerWorks can help you figure out how to generate an XML document using your preferred server-side language (see Resources for links). "<show> "<title>" . $title . "</title>"; "<rating>" . $rating . "</rating>"; "</show>";

Other options for interpreting XML One very popular options for dealing with XML, beyond treating it as unformatted text or using the DOM, is important and worth mentioning. That's JSON, short for JavaScript Object Notation, and it's a free text format that is bundled into JavaScript. I don't have room to cover JSON in this article, so I'll come back to it in just a few months; you'll probably hear about it as soon as you mention XML and Ajax apps, however, so now you'll know what your co-workers are talking about. In general, everything that you can do with JSON, you can do with the DOM, or vice versa;

it's mostly about preference, and choosing the right approach for a specific application. For now, stick with the DOM, and get familiar with it in the context of receiving a server's response. In a couple of articles, I'll spend a good amount of time on JSON, and then you'll be ready to choose between the two on your next app. So stay tuned: lots more XML is coming in the next couple of articles.

In conclusion I've talked about XML nearly non-stop since the last article in this series began, but have still really only scratched the surface of XML's contribution to the Ajax equation. In my next article, you'll look in more detail at those particular occasions in which you would want to send XML (and see in which of those cases you'll need to receive XML back as well). In particular, you'll examine Web services -- both proprietary ones and APIs like Google -- in light of Ajax interaction. Your biggest task in the short term, though, is to really think about when XML makes sense for your own applications. In many cases, if your app is working well, then XML is nothing more than a technology buzzword that can cause you headaches, and you should resist the temptation to use it just so you can say you have XML in your application. If you've a situation where the data the server sends you is limited, though, or in a strange comma- or pipe-delimited format, then XML might offer you real advantages. Consider working with or changing your server-side components so that they return responses in a more standard way, using XML, rather than a proprietary format that almost certainly isn't as robust as XML. Most of all, realize that the more you learn about the technologies around Ajax, the more careful you have to be about your decisions. It's fun to write these Web 2.0 apps (and in coming articles, you'll return to the user interface and see some of the cool things that you can do), but it also takes some caution to make sure you don't throw technologies at a working Web page just to impress your friends. I know you can write a good app, so go out and do just that. When you're finished, come back here for next month's article, and even more XML.

Mastering Ajax, Part 9: Using the Google Ajax Search API Take advantage of public APIs in your asynchronous applications Document options Print this page E-mail this page Document

Level: Intermediate options requiring Brett McLaughlin (brett@newInstance.com), Author and Editor, JavaScript are O'Reilly Media Inc. not displayed 23 Jan 2007 Making asynchronous requests isn't just about talking to your own server-side programs. You can also communicate with public APIs like those from Google or Amazon, and add more functionality to your Web applications than just what your own scripts and server-side programs provide. In this article, Brett McLaughlin teaches you how to make and receive requests and responses from public APIs like those supplied by Google. So far in this series, the focus was exclusively on situations in which your client Web pages make requests to your server-side scripts and programs. This is how probably 80 to 90 percent of Ajax applications -- asynchronous Web applications that use the XMLHttpRequest object -- work. However, there is a fairly serious limitation in this approach: you're limited by your own ingenuity and programming skills, or at least by the ingenuity and programming skills of the programmers on your team, in your company. Almost certainly, sometimes you find'll that you really want to do something, but you don't have the technical knowledge necessary to achieve that goal. Perhaps you don't know some piece of syntax, or how to come up with the right algorithm. In other cases, you might not have the data or resources (either people-resources or data-resources) to fill your needs. It's in these cases that you might find yourself thinking, "Gee, if I could just use that other person's code!" This article is meant to address that particular case. Open source scripts and programs Before I get into the meat of this article -- using public APIs in your Web applications -it's worth mentioning the existence of open source scripts and programs. Without getting too deeply into detail, open source is a term used to describe code that can be, to some degree, freely used and reused in your own applications. Consult Resources for relevant links, but at a 10,000-foot view, you can take open source code that someone else has written, and simply drop it into your own environment, without charge or (much) restriction. If you make use of open source code, sometimes you'll have to add some extra documentation to your applications, or perhaps contribute changes you make to the open source program or script back to the community. Whatever the particulars of the program that you use, the end result is that you can use code that you didn't have to write, and perhaps wouldn't have been able to write without a lot of help and resources that you don't have. Projects like Apache make it easy to take advantage of the work that others have done -- and don't worry; they want you to use their work! Articles and tutorials online It would also be pretty silly in an article published on IBM developerWorks not to mention the wealth of resources, from articles to tutorials to white papers, available on the Internet. There are literally hundreds of thousands of pieces of instruction online, and you could probably find close to a thousand articles about Ajax -- I'm already almost up to ten articles in this series alone! Most of these articles have working code, examples, downloads, and all sorts of other goodies available for your use. If you don't have the ability to code the server-side program or script you want to use, or can't find an open source program or script to do what you need, hop over to Google and try entering in a basic description of what you're looking for. You'll often find an article, or tip, or some other snippet online that might help you do just what you need. Hop over

to developerWorks and do the same; often, you'll find exactly the piece of code, or even entire script, that you were looking for, complete with helpful comments and a description of how it works.

Using public APIs Many times, you'll face a problem that isn't just technical. You don't need help writing a particular script or piece of code; rather, you need data or resources that you simply don't have. In these cases, even if a tutorial or open source script were available to help you, you'd still need more. Consider, for example, a case in which you want to place a search engine on your Web page. That presumes that you have the data that you want to search -- but what if you want to search beyond the data your company or organization has available? In cases where you are limited not by technical ability, but by data, a public API might help you solve your problem. A public API allows you to use a program hosted on someone else's servers, using someone else's data. In general, the API itself defines how you interact with the program. For instance, a public API to the Google search engine would let you make search requests, but Google's code would search Google's data, and return the results to your program. You not only get the benefit of someone else's technical skills in writing these programs, but you also get the benefit of data stores far beyond your or your company's ability to support.

Getting set up to use the Google Ajax Search API Google remains, arguably, the breakthrough application of the online era. Grandmothers and four-year-olds know about Google, even if they don't understand how anything else online works. Google runs such a massively popular and useful search engine, and seems so committed to providing (mostly) free services that it's no surprise that it has a public API available for you to use in your own programs. In this section, you'll get set up to use the Google API, and prepare to figure out exactly how you can make an asynchronous application talk to Google. Getting a developer key from Google This article will focus specifically on Google's Ajax Search API. You can find out more online about this particular API by visiting the Google Ajax Search API home page, which is shown in Figure 1. (See Resources for a link.) Figure 1. Google's Ajax Search API page

Your first step is to click the Sign up for a Google AJAX Search API key link. This will take you to a page where you can sign up to use the Google API. You'll need to accept some terms of use -- all of which are pretty harmless, as far as I can tell -- and supply the URL of the Web site where your application will run (see Figure 2). Figure 2. Signing up for Google's Ajax Search API

Once you've read the What URL should I use? agreement and checked The URL that Google asks for is more or less actually the the checkbox, enter in domain where you run your site. If you have your own your URL, click Generate domain, like I do, you can just use API Key, and wait a http://www.newinstance.com (replace my domain with second or two. At this your own, obviously). You only need to be more specific if point, you'll have to log in your site uses a subdomain or a particular path within a to Google, or create an larger domain; if that's the case, you might need to use a account. This is a pretty URL like http://www.earthlink.net/~bmclaugh or standard process, and http://brett.earthlink.net. Other than those special cases, you should be able to though, don't try to be overly specific with the URL you handle it on your own. supply to Google -- just give it the root URL you use to Once you're finished, access your entire Web site, and you can use the API you'll get a nice reply anywhere within that URL. screen back, which gives you a very long key, repeats back your URL, and even gives you a sample page. The key will look something like this: ABQIAAAAjtuhyCXrSHOFSz7zK0f8phSA9fWLQO3TbB2M9BRePlYkXeAu8lHeUgfgRs0eIWUaXg

Google's API documentation Before you start to use the key you've just been assigned, you take some time to check out Google's API documentation (there's a link at the bottom of the page that supplied your key, and that link is repeated in the Resources of this article). Even though you can get a really good start through this article, you'll find that Google's API documentation is a good read, and will probably give you some interesting ideas for how you can use Google on your own site, in your own unique applications.

The simplest Google search Web application To get you used to seeing what's possible, let's take the sample Web page that Google provides, change it up just a bit, and see how it works. Creating a search box Listing 1 shows a pretty simple Web page; go ahead and type it into your favorite editor, save it, and upload it to the domain or URL that you supplied to Google in the previous section. Listing 1. The HTML for a simple Google search application <html> <head> <title>My Google AJAX Search API Application</title> <link href="http://www.google.com/uds/css/gsearch.css" type="text/css" rel="stylesheet" /> <script src="http://www.google.com/uds/api?file=uds.js&v=1.0&key= YOUR KEY HERE " type="text/javascript"> </script> <script language="Javascript" type="text/javascript"> function OnLoad() { // Create the Google search control var searchControl = new GSearchControl(); // These allow you to customize what appears in the search results var localSearch = new GlocalSearch(); searchControl.addSearcher(localSearch); searchControl.addSearcher(new GwebSearch()); searchControl.addSearcher(new GvideoSearch()); searchControl.addSearcher(new GblogSearch()); // Tell Google your location to base searches around localSearch.setCenterPoint("Dallas, TX"); // "Draw" the control on the HTML form searchControl.draw(document.getElementById("searchcontrol")); } </script>

</head> <body onload="OnLoad()"> <div id="searchcontrol" /> </body> </html> Be sure to replace the bolded text with your own developer key from Google. When you load the page, you'll get something that looks a lot like Figure 3. Figure 3. The simplest search form for Google

There's not much to it, but all the power of Google is sitting behind that little control. Running a search Type in a search term and click Search to send Google into action. You'll quickly see several results pop up, as shown in Figure 4. Figure 4. Google's search results

Adding in a pre-search Obviously, the page looks a whole lot better once you do a search; the video, blogs, and search results give the page a nicer look. Thus, you might want to add a pre-search -- a search term that you define, the results of which will come up the first time a user loads your page. To do that, just add the bolded line in Listing 2 into your JavaScript. Listing 2. Adding a pre-search term function OnLoad() { // Create the Google search control var searchControl = new GSearchControl(); // These allow you to customize what appears in the search results var localSearch = new GlocalSearch(); searchControl.addSearcher(localSearch); searchControl.addSearcher(new GwebSearch()); searchControl.addSearcher(new GvideoSearch()); searchControl.addSearcher(new GblogSearch()); // Tell Google your location to base searches around localSearch.setCenterPoint("Dallas, TX"); // "Draw" the control on the HTML form searchControl.draw(document.getElementById("searchcontrol"));

searchControl.execute("Christmas Eve"); } Obviously, you can insert your own initial search term into your code to customize what comes up when the page loads. JavaScript breakdown Before I move on, take a quick look at what these basic commands do. First, a new GSearchControl is created, as illustrated in Listing 3. This is the construct that lets you do all the searching: Listing 3. Creating a new GSearchControl function OnLoad() { // Create the Google search control var searchControl = new GSearchControl(); ... } Next, the code sets up a new local search, using a GlocalSearch; this is a special Google construct that allows you to perform a search based on a specific location. The local search is illustrated in Listing 4. Listing 4. Setting up a new local search function OnLoad() { // Create the Google search control var searchControl = new GSearchControl(); // These allow you to customize what appears in the search results var localSearch = new GlocalSearch(); ... // Tell Google your location to base searches around localSearch.setCenterPoint("Dallas, TX"); ... } This is all pretty self-explanatory, once you learn the objects and methods to call. The code in Listing 4 creates a new local searcher, and then sets the center point of the search.

Next up in Listing 5 are several lines that tell the search control exactly what types of searches it should perform. Listing 5. Search types to allow function OnLoad() { // Create the Google search control var searchControl = new GSearchControl(); // These allow you to customize what appears in the search results var localSearch = new GlocalSearch(); searchControl.addSearcher(localSearch); searchControl.addSearcher(new GwebSearch()); searchControl.addSearcher(new GvideoSearch()); searchControl.addSearcher(new GblogSearch()); // Tell Google your location to base searches around localSearch.setCenterPoint("Dallas, TX"); ... } You can look up most of these search types, here's a short summary:
y y y

GwebSearch: An object for searching the Web, which is what Google is best known for. GvideoSearch: This object looks for video related to your search terms. GblogSearch: This object focuses specifically on searching through blogs, which are structured and tagged a bit differently from other Web content types.

You've already seen how to pre-load a specific search. All that's left, then, is the draw() method call, illustrated in Listing 6. You give this call a DOM element in your HTML (for a refresher on the DOM, check out previous articles in this series in the Resources). The control will then magically appear on your form, ready for use. Listing 6. Drawing the search control function OnLoad() { // Create the Google search control var searchControl = new GSearchControl(); // These allow you to customize what appears in the search results var localSearch = new GlocalSearch(); searchControl.addSearcher(localSearch); searchControl.addSearcher(new GwebSearch()); searchControl.addSearcher(new GvideoSearch());

searchControl.addSearcher(new GblogSearch()); // Tell Google your location to base searches around localSearch.setCenterPoint("Dallas, TX"); // "Draw" the control on the HTML form searchControl.draw(document.getElementById("searchcontrol")); searchControl.execute("Christmas Eve"); }

But where's the Ajax? It's actually not readily apparent where the asynchrony happens in this simple search box. Sure, it's pretty cool that you can throw up a Google search box somewhere within your own Web application, but this is still a series on Ajax apps, not Google searches. So where's the Ajax? Enter in a search term and click the Search button, and you'll notice a very Ajaxian response: the search results come up without a page reload. That's one of the hallmarks of most Ajax apps -- the visible content changing without reloading pages. Clearly, something is going on beyond the normal request/response model. But where is XMLHttpRequest? Where is the request object that you've learned about for so many articles? And other than that one getElementById() method, where is the DOM and page manipulation? Well, it's all wrapped up in two lines within your HTML. Google takes care of the JavaScript The first line of note is one I haven't talked much about yet, and it's illustrated in Listing 7. Listing 7. The all-important JavaScript file <script src=" http://www.google.com/uds/api?file=uds.js &v=1.0&key=[YOUR GOOGLE KEY]" type="text/javascript"> </script> The syntax here isn't particularly interesting, but the point is that Google hosts a file named uds.js, which has within it all the JavaScript needed for the search box to operate. This is using someone else's code in the truest sense: you're even letting the third party host the code your application uses. That's pretty significant, because Google handles upkeep and maintenance, and when the company upgrades the JavaScript file, you get the benefits automatically. Google won't change the API without letting you know, so your code will keep working even if the JavaScript file is changed. The GSearchControl object The other thing somewhat hidden from view is the code for the GSearchControl object,

created in the onLoad() JavaScript function. All you have to do to create this object is invoke the code in Listing 8. Listing 8. Creating a GSearchControl object // Create the Google search control var searchControl = new GSearchControl(); The necessary HTML is also pretty bland: just a div tag with an ID that your JavaScript can refer to, as shown in Listing 9. Listing 9. All the HTML you'll need to create a search control <div id="searchcontrol" /> But, again, behind the scenes, What does Google's JavaScript look like? Google's code is doing all sorts of Google's JavaScript isn't so easy to get at. First, the things. It's creating a new text uds.js JavaScript file figures out some locality box, some iconic graphics, and a settings, handles some Google-specific tasks, button that calls a JavaScript verifies your Google key, and then loads two other function, also in Google's scripts: JavaScript. So you get all sorts of http://www.google.com/uds/js/locale/en/uistrings.js behavior for free; while you and should understand the basics of http://www.google.com/uds/js/uds_compiled.js. how this happens, it's convenient You can actually pull up these two files and wade that you can simply use this code, through them if you're interested, but beware: it's and get on with the rest of your tough going through advanced code, and the application. formatting is awful! For most of you, simply Ajax is more than just the code you knowing how to use these files should be your goal, write rather than worrying too much about what they do So Ajax apps aren't just about you at a line-by-line level. using XmlHttpRequest; they're about a way to approach Web applications, and are based upon asynchrony. Even though you didn't write any Ajax-specific code, you have created an Ajax app. Thank Google: it did most of the work, and you get the benefit!

Going further with Google's Ajax Search API At this point, it's up to you to take these steps and adapt them to your own applications. At the simplest end of the spectrum, you can drop a div into your own Web pages and add the JavaScript shown in Listing 1 to your Web page; you'll have Google search all ready for use. But the fun doesn't have to stop there. You don't need to limit yourself to this specific set of options or controls. Play around with the Web results, the blog results, and the video results, and integrate each into your Web applications where appropriate. You might

want to offer multiple search controls, each of them focusing on a specific type of result. You might want to include the Google search control in a span element, right in the middle of the rest of your app's content, rather than off to the side in a div. Whatever the case, you really should ensure that Google's search is molded to fit your needs, rather than modifying your applications to suit Google.

In conclusion It shouldn't be hard to build on what you've learned here and start to add Google search boxes and other uses of the Google API to your own Ajax apps. More importantly, though, you should now have a pretty good idea of how to use public APIs in general. For example, Amazon.com offers a public API that allows you to perform the same kind of Web searches you performed with Google on books and other merchandise from Amazon's store. You can start to hunt around for your own favorite public APIs, and move beyond just what your own coding skills allow for. In fact, you can very easily create a site that integrates with Google, Amazon.com, Flickr, and much more. So while it's important to get a handle on how to use Google -Share this... because of the search algorithms and enormous data stores that Google offers -- it's even more important to learn how to use any Digg this story public API. You should also start thinking about your application as more than a sum of your coding skills; instead, it can simply be a Post to gateway to various pieces of data. That data might be stored on the del.icio.us servers of Google, Amazon.com, del.icio.us, or anywhere else. Add to that your own business's or project's take on that data, and Slashdot it! you've got a very powerful and robust solution that goes well beyond what you could code on your own. So go out and make big applications. Use data from all sorts of places, and don't be confined by what you've coded yourself. Enjoy, and I'll come back to some more technical issues, like data formats, in the next article of this series.

Mastering Ajax, Part 10: Using JSON for data transfer Work natively with JavaScript objects Document options Print this page E-mail this page Document options requiring

Level: Introductory JavaScript are not displayed Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc. 27 Mar 2007 Rate this page Plain text and XML are both data formats that you can use for sending and receiving information in your Help us asynchronous applications. This installment of improve this Mastering Ajax looks at another useful data format, content JavaScript Object Notation (JSON), and how it makes moving data and objects around in your applications easier. If you've been reading this series for long, you've received an extensive education in data formats. Earlier articles examined how plain text and simple name/value pairs work great in many asynchronous applications. You can assemble data that looks like this: firstName=Brett&lastName=McLaughlin&email=brett@newInstance.com There's no need to do anything more. In fact, Web veterans will recognize this as the format for information sent through GET requests. Then the series looked at XML. Obviously, XML has received its fair share of press (both negative and positive), and it's no surprise that it shows up in Ajax applications. You can review earlier articles in this series to see how XML provides an alternative data format: <request> <firstName>Brett</firstName> <lastName>McLaughlin</lastName> <email>brett@newInstance.com</email> </request> This is the same data you saw above, but this time it's stored in an XML format. There's nothing remarkable going on here; it's just a different data format that allows you to use XML instead of plain text and name/value pairs. This article takes on yet another data format, called JavaScript Object Notation, or JSON. JSON looks a bit like what you've seen already, and a bit like nothing you've ever seen before. It will give you another choice, and having choices is a good thing. The power to choose Before digging into the details of the JSON format, you should understand why it's worth spending another couple of articles on another data format (yes, the next article in this series will deal with JSON as well), especially when you already know how to work with both XML and name/value pairs in plain text. In a nutshell, though, it's simple: The more choices you have, and the more options you have for any problem, the better your chances are of finding the best solution to a problem, rather than just a solution. Recapping name/value pairs and XML This series has already touched a good bit on those situations in which name/value pairs make sense, as well as those in which XML might be a better choice. To recap quickly, your first thought should always be to use

name/value pairs. Doing so is almost always the simplest solution to the problems in most asynchronous applications, and it doesn't require anything but a very basic knowledge of JavaScript. You really shouldn't even worry about using an alternate data format unless you have some sort of constraint that moves you towards XML. Obviously, if you're sending data to a server-side program that requires XML-formatted input, then you will want to use XML as your data format. In most cases, though, XML turns out to be a better choice for the servers that need to send your application multiple pieces of information; in other words, XML is more commonly used for responses to Ajax applications, rather than requests from Ajax applications. Adding JSON to the mix When you're using either name/value pairs or XML, you're essentially taking data from the application using JavaScript and stuffing it into a data format. In these cases, JavaScript is functioning largely as a data manipulation language, moving and manipulating data from Web forms and putting it into a format that can be easily sent to a server-side program. However, there are times when you'll use JavaScript as more than just a format language. In these cases, you're actually using objects in the JavaScript language to represent data, and going beyond just shuttling data from Web forms into requests. In these situations, it's more work to extract data from the objects in JavaScript and then stuff that data into name/value pairs or XML. This is where JSON shines: It allows you to easily turn JavaScript objects into data that can be sent as part of a request (synchronous or asynchronous). The bottom line is that JSON isn't some sort of magic bullet; it is, however, a great option for some very specific situations. Rather than assuming that you won't ever encounter those situations, read this article and the next in the series to learn about JSON, so you'll be equipped when you do run into those types of problems.

JSON basics At its simplest, JSON allows you to transform a set of data represented in a JavaScript object into a string that you can easily pass from one function to another, or -- in the case of asynchronous applications -- from a Web client to a server-side program. The string looks a little odd (you'll see some examples in just a moment), but it's easily interpreted by JavaScript, and JSON allows you to represent structures more complex than name/value pairs. For instance, you can represent arrays and complex objects, rather than just simple lists of keys and values. Simple JSON examples At its very simplest, you can represent what is essentially a name/value pair in JSON like this: { "firstName": "Brett" }

This is pretty basic and actually takes up more space than the equivalent name/value pair in clear text: firstName=Brett However, JSON illustrates its value when you start to string together multiple name/value pairs. First, you can create what is essentially a record of data, with multiple name/value pairs, like this: { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" } There's still not much advantage here over name/value pairs in terms of syntax, but in this case JSON is significantly easier to use, and has some readability advantages. For example, it's clear that all three of the values above are part of the same record; the brackets establish that the values have some connection. Arrays of values When you need to represent a set of values, JSON starts to be not only more readable, but less verbose. Say, for example, that you want to have a list of people. In XML, you'd be stuck with lots of opening and closing tags, and if you were using typical name/value pairs -- the kind we've looked at in earlier articles in this series -- then you'd have to come up with a proprietary data format, or perhaps modify the key names to something like person1-firstName. With JSON, you can simply group multiple bracketed records: { "people": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" }, { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" }, { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" } ]} This isn't too hard to understand. In this case, there's a single variable, named people, and the value is the array containing three items, each of which is a person record with a first name, a last name, and an e-mail address. The example above illustrates how you can throw records together, and also group the items into a single value with brackets around it. Of course, you could use the same syntax, but have multiple values (each with multiple records): { "programmers": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" }, { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" }, { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" }

], "authors": [ { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" }, { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" }, { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" } ], "musicians": [ { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" }, { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" } ] } The most obvious thing to note here is your ability to represent multiple values that each in turn have multiple values. What you should also notice, though, is that the actual name/value pairs in the records change across the different main entries (programmers, authors, and musicians). JSON is completely dynamic and lets you change the way you represent data in the middle of your JSON structure. To put it another way, there is no predefined set of constraints that you need to follow when working with JSON-formatted data. So you can change how you represent things, or even represent the same thing in different ways, all within the same data structure.

Using JSON in JavaScript After you've got a handle on the JSON format, it's simple to use it within JavaScript. JSON is a native JavaScript format, meaning simply that you don't need any special API or toolkit to work with JSON data within JavaScript. Assigning JSON data to a variable For example, you can simply create a new JavaScript variable and then directly assign a string of JSON-formatted data to it: var people = { "programmers": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" }, { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" }, { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" } ], "authors": [

{ "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" }, { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" }, { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" } ], "musicians": [ { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" }, { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" } ] } There's nothing complicated going on here; now people contains the JSON formatted data we've been looking at throughout this article. However, this doesn't do much, as the data still isn't in a format that is obviously useful. Accessing the data While it might not be obvious, that lengthy string above is just an array, and once you've got that array in a JavaScript variable, you can access it easily. In fact, you can simply separate the array with period delimiters. So, to access the last name of the first entry of the programmers list, you would use code like this in your JavaScript: people.programmers[0].lastName; Take note that the indexing is zero-based. So this begins with the data in the people variable; it then moves to the item called programmers and pulls off the first record ([0]); finally, it accesses the value for the lastName key. The result is the string value "McLaughlin". Here are a few more examples using the same variable. people.authors[1].genre people.musicians[3].lastName refers to the fourth entry, and there isn't one people.programmers.[2].firstName // Value is "fantasy" // Undefined. This

// Value is "Elliotte"

With this little bit of syntax, you can work with any variety of JSON-formatted data, all without any extra JavaScript toolkits or APIs. Modifying JSON data Just as you can access data with the dot and bracket notation shown above, you can easily modify data in the same way: people.musicians[1].lastName = "Rachmaninov";

That's all you need to do to change data in a variable once you've converted from a string to JavaScript objects. Converting back to strings Of course, all that data modification isn't of much value if you can't easily convert back into the textual format mentioned in this article. That's also trivial in JavaScript: String newJSONtext = people.toJSONString(); That's all there is to it! Now you've got a string of text that you can use anywhere you like -- you could use it as the request string in an Ajax application, for instance. Perhaps even more importantly, you can convert any JavaScript object into JSON text. You don't have to work only with variables that were originally assigned a JSON-formatted string. To transform an object named myObject, you would simply issue the same sort of command: String myObjectInJSON = myObject.toJSONString(); This is the biggest difference between JSON and other data formats this series has explored. With JSON, you call a simple function and get your data, formatted and ready for use. With other data formats, it's your job to handle the conversion between the raw data and the formatted data. Even when using an API like the Document Object Model that provides a function that converts from its own data structure into text, you've got to learn the API and use that API's objects, rather than native JavaScript objects and syntax. The end result is that when you're already working with lots of JavaScript objects, JSON is almost certainly a good bet for you to easily convert your data into a format that is simple to send in your requests to server-side programs.

Conclusion This series has spent a lot of time looking at data formats, mostly because your asynchronous applications are ultimately almost all about data. If you have a variety of tools and techniques that will let you send and receive all kinds of data -- and do it in the best, most efficient manner for each data type -- then you're well on your way to being an Ajax pro. Add JSON to what you've already got available in using XML and plain text, and you're equipped for even more complex data structures in JavaScript. The next article in this series goes beyond just sending data, and dives into how server-side programs can receive -- and deal with -- JSON-formatted data. I'll also look at how server-side programs can send back data in the JSON format across scripts and server-side components, making it possible to mix and match XML, plain text, and JSON requests and responses. The goal is flexibility, and you're well on your way to being able to put all these tools together, in almost any combination you can imagine.

Mastering Ajax, Part 11: JSON on the server side Responding to and replying with JSON in your server-side scripts and programs Document options Print this page E-mail this page Document options requiring JavaScript are

Level: Advanced not displayed Brett McLaughlin (brett@newInstance.com), Author and Editor, O'Reilly Media Inc. Rate this page 14 Aug 2007 In the last article, you learned how to take an object in Help us JavaScript and convert it into a JSON representation. That improve this format is an easy one to use for sending (and receiving) content data that maps to objects, or even arrays of objects. In this final article of the series, you'll learn how to handle data sent to a server in the JSON format and how to reply to scripts using the same format. JSON's real value As discussed in the previous article in this series, JSON is a useful format for Ajax applications because it allows you to convert between JavaScript objects and string values quickly. Because Ajax apps are best suited to send plain text to server-side programs and receive plain text in return, an API that generates text is almost always preferable over an API that doesn't; further, JSON allows you to work with native JavaScript objects and not worry about how those objects will be represented. XML provides the same textual benefits, but the APIs The developerWorks for converting JavaScript objects into XML (and there Ajax resource center are a few) aren't as mature as the JSON APIs; you'll Check out the Ajax sometimes have to take care in creating and working Resource Center, with your JavaScript objects to ensure that you're doing your one-stop shop things that can work with the XML conversion API for information on you've chosen. The same isn't true with JSON: it the Ajax handles pretty much every conceivable object type and programming model, simply gives you back a nice JSON data representation. including articles and So the biggest value of JSON is that you can work with tutorials, discussion JavaScript as JavaScript, not as a data-format forums, blogs, wikis, language. All the things you learn about using events, and news. If JavaScript objects can be applied to your code without it's happening, it's worrying about how those objects will be converted to covered here. text. Then, you make a simple JSON method call: String myObjectInJSON = myObject.toJSONString(); and you're ready to send the resulting text onto a server.

Getting JSON to the server Sending JSON to the server isn't particularly difficult, but it is crucial, and you still have a few choices to make. However, once you've already chosen to use JSON, the choices are a lot simpler and quite a bit more limited, so there's not as much to think or worry about. The bottom line is you just need to get your JSON string to the server, preferably as quickly and as simply as possible. Sending JSON in name/value pairs via GET

The easiest way to get your JSON data to the server is to convert it to text, and send it as the value of a name/value pair. Remember, your JSON-formatted data is just one fairly long object, and probably looks something like Listing 1: Listing 1. A simple JavaScript object in JSON format var people = { "programmers": [ { "firstName": "Brett", "lastName":"McLaughlin", "email": "brett@newInstance.com" }, { "firstName": "Jason", "lastName":"Hunter", "email": "jason@servlets.com" }, { "firstName": "Elliotte", "lastName":"Harold", "email": "elharo@macfaq.com" } ], "authors": [ { "firstName": "Isaac", "lastName": "Asimov", "genre": "science fiction" }, { "firstName": "Tad", "lastName": "Williams", "genre": "fantasy" }, { "firstName": "Frank", "lastName": "Peretti", "genre": "christian fiction" } ], "musicians": [ { "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" }, { "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" } ] } So you could send this to a server-side script as a name/value pair like this: var url = "organizePeople.php?people=" + people.toJSONString(); xmlHttp.open("GET", url, true); xmlHttp.onreadystatechange = updatePage; xmlHttp.send(null); This looks good, but there's one problem: you've got spaces and all sorts of characters in your JSON data string that a Web browser might try and interpret. To ensure that these characters don't mess things up on the server (or in transmission of your data to the server), add in the JavaScript escape() function, like this: var url = "organizePeople.php?people=" + people.toJSONString() ) ; request.open("GET", url, true); request.onreadystatechange = updatePage; request.send(null); This function handles whitespace, slashes, and anything else that might trip up browsers and converts them to Web-safe characters (for example, an empty space is converted to %20, which browsers don't treat as a space but instead escape(

pass on to a server unchanged). Then servers will (generally automatically) convert these back to what they are supposed to be after transmission. The downside to this approach is twofold:
y

y

You're sending potentially huge chunks of data using a GET request, which has a length limitation on the URL string. It's a big length, granted, but you never know how long an object's JSON string representation could get, especially if you're using pretty complex objects. You're sending all your data across the network as clear text, which is about as unsecure as you can manage to get when it comes to sending data.

To be clear, these are both limitations of GET requests, rather than anything related to JSON data specifically. However, they're very real concerns when you're sending more than just a user's first or last name, or maybe selections on a form. Once you start to deal with anything that might be even remotely confidential, or extremely lengthy, then you should look at using POST requests. POSTing JSON data When you decide you want to move to using a POST request for sending your JSON data to the server, you don't have to make a lot of code changes. Here's what you'd want: var url = "organizePeople.php?timeStamp=" + new Date().getTime(); request.open("POST", url, true); request.onreadystatechange = updatePage; request.setRequestHeader("Content-Type", "application/x-www-formurlencoded"); request.send(people.toJSONString()); Most of this code should be familiar to you from " Mastering Ajax, Part 3: Advanced requests and responses in Ajax," which focuses on sending POST requests. The request is opened using POST instead of GET, and the ContentType header is set to let the server know what sort of data it should expect. In this case, that's application/x-www-form-urlencoded, which lets the server know you're just sending across text like it would get from a normal HTML form. One other quick note is that the URL has the current time appended to it. That ensures that the request isn't cached after it's sent the first time but is recreated and resent each time this method is called; the URL will be subtly different because of the changing time stamp. This is a common trick to ensure that POSTing to a script actually repeatedly generates a new request each time, and the Web browser doesn't try and cache responses from the server. JSON is just text Whether you use GET or POST, the big deal here is that JSON is ultimately just text data. You can easily manipulate it and get it to the server because it doesn't require any special encoding, and every server-side script in the world can handle text data. If JSON were a binary format or had some strange textual encoding, that wouldn't be the case; as it is, though, JSON is just normal text data -- like a script would receive from a form submission, as you saw in the POST section and Content-Type header -- so you don't have a lot to worry about

when sending it to a server.

Interpreting JSON on the server Once you've written your client-side JavaScript code, allowed your users to interact with your Web forms and pages, and gathered information that you need to send on to a server-side program for processing, you're to the point where the server becomes the major player in your application (and probably well into what we all think of as "Ajax applications," assuming you've made the call to the server-side program you're using asynchronous). It's here where the choices you made on the client, like using JavaScript objects and then converting them to JSON strings, must be matched by decisions on the server, like which API to use to decode your JSON data. The JSON two-step Working with JSON on the server side is essentially a two-step process, no matter what language you're using on the server: 1. Find a JSON parser/toolkit/helper API for the language you're using to write your server-side programs. 2. Use the JSON parser/toolkit/helper API to take the request data from the client and turn it into something your script can understand. That's really all that there is to it. Let's take each step in a little more detail. Find a JSON parser The best resource for finding a JSON parser or toolkit is the JSON Web site (see Resources for a link). In addition to learning a lot about the format itself, this page has links to JSON tools and parsers for everything from ASP to Erlang to Pike to Ruby. Simply find the language your scripts are written in and download a toolkit. Drop that or expand that or install that (there's a lot of variability when you could be using C#, or PHP, or Lisp on the server) so that your scripts and programs on the server can use the toolkit. For example, if you're using PHP, you could simply upgrade to PHP 5.2 and be done with it; this recent version of PHP includes the JSON extension by default. In fact, that's almost certainly the best way to handle JSON when you're working with PHP. If you're using Java servlets, the org.json package, hosted at json.org, is a simple choice. In this case, you'd download json.zip from the JSON Web site and add the included source files to your project's build directory. Compile these files, and you're ready to go. Similar steps hold true for the other languages supported; your own expertise using the language you prefer is the best guide. Using your JSON parser Once you've got the resources available to your program, it's just a matter of finding the right method to call. For example, suppose you were using the JSON-PHP module with PHP: // This is just a code fragment from a larger PHP server-side script require_once('JSON.php');

$json = new Services_JSON(); // accept POST data and decode it $value = $json->decode($GLOBALS['HTTP_RAW_POST_DATA']); // Now work with value as raw PHP With that, you've got all the data -- array format, multiple rows, single values, whatever you stuffed into your JSON data structure -- into a native PHP format, in the $value variable. If you were using the org.json package in a servlet, you'd use something like this: public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { StringBuffer jb = new StringBuffer(); String line = null; try { BufferedReader reader = request.getReader(); while ((line = reader.readLine()) != null) jb.append(line); } catch (Exception e) { //report an error } try { JSONObject jsonObject = new JSONObject(jb.toString()); } catch (ParseException e) { // crash and burn throw new IOException("Error parsing JSON request string"); } // Work with the data using methods like... // int someInt = jsonObject.getInt("intParamName"); // String someString = jsonObject.getString("stringParamName"); // JSONObject nestedObj = jsonObject.getJSONObject("nestedObjName"); // JSONArray arr = jsonObject.getJSONArray("arrayParamName"); // etc... } You can refer to the org.json package documentation (links in the Resources section) for more details. (Note: If you want more detail on the org.json or other JSON toolkits, e-mail me and let me know. Hearing from you helps me decide what to write about!).

In conclusion

You should have a handle now on how to deal with JSON from a technical standpoint on the server-side. This article and Part 10 of the series, beyond just being technical assists, should also convince you that JSON is a pretty flexible, powerful data format. Even if it's not what you use on every application, good Ajax and JavaScript programmers should have JSON in their toolbox and be able to select it for use any time a need arises. I'd certainly like to hear more about your own experiences with JSON and what languages you're finding work well -- and not so well -- on the server for dealing with JSON data. Hop on the Java and XML newsgroup (links in Resources) and let me know. Enjoy JSON and the power of textual data formats.

http://www.ibm.com/developerworks/views/web/libraryview.jsp?search_by=Mastering+Ajax

Sign up to vote on this title
UsefulNot useful