8.3. The XMLHttpRequest ObjectAs interesting as the previous section may have been, remember that it was only an appetizer. Now the time has come for the entrée: the XMLHttpRequest object. If you've never used the XMLHttpRequest object, it is, as described previously, an object that gives web browsers the capability to communicate directly with the server, without the unload/reload cycleor "blink," as the peasants call it. 8.3.1. Avoiding the Unload/Reload CycleThe best analogy that I can think of to the XMLHttpRequest object is the transporter from any of the various incarnations of Star Trek. With the transporter, only the personnel essential to a particular mission need go down to the planet's surface. The alternative would be to either land the Starship, if it were capable of planetary landings, or send a shuttlecraft. In either case, there would be a lot of unnecessary equipment and personnel being moved about at great expense, as opposed to the "move only what you need" philosophy of the transporter. The XMLHttpRequest object is the web equivalent of the transporter. Why transmit an entire web page when all that is really needed is the data itself? The HTML and JavaScript for presentation are already there, so just change the data and we're good to go. I should point out that although the data being beamed from the server to the client doesn't necessarily have to be XML, in all these examples, it is XML. 8.3.2. Browser DifferencesBefore describing the actual syntax necessary to use XMLHTTP, I recommend that you sit down because I don't want to shock you or anything. Sitting down? Good. The syntax used for the XMLHttpRequest object is different in Microsoft Internet Explorer than from every other browser that supports it. In fact, from Microsoft's perspective, somewhere on the surface of Charon, not even the World Wide Web Consortium got it right. As a matter of fact, they made exactly the same mistake as Firefox. Fortunately, because the error is consistent among all nonInternet Explorer browsers all that is necessary is to code for IE and everybody else. Mmm, I wonder if maybe...nah! The first thing is to create an instance of the XMLHttpRequest object in the following manner: try { var x = new DOMParser(); var _IE = false; } catch(e) { var _IE = true; }; var _XMLHTTP; if(_IE) _XMLHTTP = new ActiveXObject('Microsoft.XMLHTTP'); else _XMLHTTP = new XMLHttpRequest(); Before proceeding any further, a couple of decisions must be made that involve just how we'd like the page to work. Synchronous or asynchronous? GET or POST? The choice of synchronous or asynchronous is a relatively big one, but it boils down to waiting for a response or being notified when there is a response. As long as you remember to specify a state change handler for responses to asynchronous requests, things should work. The GET or POST question is also an important decision. Fortunately, it is the same decision that has been around ever since the introduction of HTML forms, so as long as we follow the same rules, everything will be alright. Let's say, for instance, that we want to retrieve the XML file of states and provinces shown in Listing 8-8 from the server. The first thing that is needed is to determine the browserbasically, Microsoft Internet Explorer and everyone else. The next task is to create an instance of the XMLHttpRequest object, followed by setting the event handler, for asynchronous requests. Finally, the XMLHttpRequest object is opened with three parameters:
However, you must remember one thing about coding a state change handler. It is a state change handler, not an "I'm finished" handler. There are other states than "complete"; we're interested in 4, which indicates that the request is complete. Listing 8-9 shows a page that retrieves the XML from Listing 8-8, storing it in an XML Data Island and binding it for display purposes. Listing 8-8. Sample XML Document
Listing 8-9. HTML Document Using an XML Data Island
Essentially, the JavaScript in Listing 8-9 makes an asynchronous XMLHTTP request. This entails, beyond the usual "which browser is it?" stuff, creating an instance of the XMLHttpRequest object, setting an event handler for the response, and making the request using the request type, the URL, and TRue for asynchronous. The state change handler, er, handles the response from the server. If you look closely, you'll see a condition testing the readyState property to see if it is equal to 4, which is complete. The reason for testing the readyState property is that this handler fires multiple times for different reasons, ranging from the equivalent of "I'm sitting here" to "Hey, I'm getting a response." The previous example illustrated how to use the XMLHttpRequest object to asynchronously obtain an XML document from a file located on the server. Think of it as something along the lines of a proof of concept because the odds are against the XML document needed sitting in a folder on the web server. Instead, there will probably be some script version of Igor sitting around watching Oprah, waiting for some real work to do. Several different methods exist for getting data to and from our virtual Igor, ranging from a simple custom approach to slightly more complex XML-based standards. One of the standards that can be used to get the virtual Igor moving is called XML Remote Procedure Calling, or XML-RPC, for short. In a nutshell, XML-RPC is a World Wide Web Consortium Recommendation that describes a request/response protocol. A request is posted to the web server, and the web server acts upon the request and returns a response. This entire process might sound rather complex, but it really isn't any more difficult than what we've already accomplished. The only differences are that instead of a GET, we'll be doing a POST, and the request needs to be in XML, as shown in Listing 8-10 and the response in Listing 8-11. Listing 8-10. XML-RPC Request
Listing 8-11. XML-RPC Response
As you've probably deduced from this, the structure of the XML document goes along the lines of methodCall, params, param, value, and, finally, data type (integer, in this instance). The rule for the structure goes along the lines of one methodResponse, one params, and at least one param. In addition, each param can have only one valueno more, no less. Values, in turn, have a single node that both describes and holds the data. Table 8-1 shows the valid data types for XML-RPC.
Of course, communicating a single item of information as shown is pretty rare. More common are more complex data structures, such as arrays or the record-line structs. Both arrays and structs work pretty much along the same lines as the simpler example earlier. Listing 8-12 shows an example of an array, and Listing 8-13 shows an example of a struct. Listing 8-12. XML-RPC Array
Listing 8-13. XML-RPC Struct
The array example shown is merely an elaboration of the earlier simple XML document, but the struct example is more complex. Along with specifying the parameter type and value, it specifies the name of the parameter. This might not seem like much, but it is useful in applications with so many parameters that it becomes difficult to keep their relative positions straight. This leads us to the question, what does the response look like when the relative positions aren't kept straight? That's simple enough; a fault like the one in Listing 8-14 is returned. Listing 8-14. XML-RPC Fault
Now that we know what the request looks like ordinarily, the next step is to modify the previous example, in which the XSLT was retrieved through the XMLHttpRequest object and a GET to use XML-RPC. This time, however, we skip the examples and progress directly to what is considered by some the protocol of choice when creating web services: SOAP. 8.3.3. Cleaning Up with SOAPOther than being something for cleaning, SOAP is an acronym for Simple Object Access Protocol, a protocol used to communicate between web browsers and web servers. SOAP is probably one of the more difficult subjects to research on the web, if for no other reason than the multiple websites that deal with the original SOAP. Nevertheless, when searching, you eventually will obtain the desired results and discover that SOAP is nothing more than a wrapper for XML. XML-RPC was designed to provide a standard structure. However, with SOAP, a slightly different approach was used. Instead of the strict params-param-value used by XML-RPC, which rigidly ties the information with the wrapper, SOAP uses a more flexible envelope method. As with a physical envelope, a SOAP envelope both identifies the recipient and contains the message within. The only real difference between a SOAP envelope and a physical envelope is that the message contained by a SOAP envelope must be well formed, like the one shown in Listing 8-15. Listing 8-15. SOAP Request
As with the XML-RPC example, there are two possible responses to a SOAP request. Either the web service worked and returned a SOAP response, as shown in Listing 8-16, or some kind of error occurred, and the request failed and a SOAP fault was returned. Listing 8-17 contains an example of a SOAP fault. Listing 8-16. SOAP Response
Listing 8-17. SOAP Fault
|