AJAX In Action [95]
The content-centric style that we’ve applied so far has used an IFrame to receive the server-generated content. An alternative approach that might be considered content-centric is to generate a fragment of HTML in response to Licensed to jonathan zheng 182 CHAPTER 5 The role of the server an asynchronous request, and assign the response to the innerHTML of a DOM element in the current document. We use that approach in chapter 12 in our XSLT-driven phonebook, so we won’t reproduce a full example here. 5.4.4 Thinking like a plug-in: script-centric interactions When we send a JavaScript file from our web server to a browser, and it executes in that browser for us, we are actually doing something quite advanced. If we generate the JavaScript that we are sending from a program, we are setting up an even more complex system. Traditionally, client/server programs communicate data to one another. Communicating executable, mobile code across the network opens up a lot of flexibility. Enterprise-grade network languages such as Java and the .NET stack are only just catching on to the possibilities of mobile code, through technologies such as RMI, Jini, and the .NET Remoting Framework. We lightweight web developers have been doing it for years! As usual, Ajax lets us do a few new interesting things with this capability, so let’s see what they are. Overview In a classic web application, a piece of JavaScript and its associated HTML are delivered in a single bundle, and the script is typically authored to work with that particular page. Using Ajax, we can load scripts and pages independently of one another, giving us the possibility of modifying a particular page in a number of different ways, depending on the script that we load. The code that constitutes our client-tier application can effectively be extended at runtime. This introduces both problems and opportunities, as we will see. Figure 5.8 illustrates the basic architecture of a script-centric application. The first advantage of this approach over a content-centric solution is that the network activity is relegated to the background, eliminating visual blinking. The exact nature of the script that we generate will depend on the hooks that we expose in the client tier itself. As with much code generation, success hinges on keeping the generated portion simple and making use of nongenerated library code where possible, either transmitted alongside the generated code or resident in the client application. Either way, this pattern results in relatively tight coupling between the tiers. That is, the code generated by the server requires intimate knowledge of API calls on the client. Two problems emerge. First, changes to the server and client code can unintentionally break them. Good modular design principles can offset this to some extent, by providing a well-defined, well-documented API—implementing the Façade pattern. The second issue is that the stream of JavaScript is very Licensed to jonathan zheng The details: exchanging data 183 Client Server Hidden inner frame 1. Request Title Item Item 2. Response 3. Interpret Item var title="ABC"; var items={ 4. Update visible elements "1", "2", "3" } show(title,items); Figure 5.8 Script-centric architecture in an Ajax application. The client application makes a request to the server for a fragment of JavaScript, which it then interprets. The client app exposes several entry points for generated scripts to hook into, allowing manipulation of the client by the script. specifically designed for this client, and it is unlikely to be as reusable in other contexts in comparison to, say, a stream of XML. Reusability isn’t important in all cases, however. Let’s have a look at our planetary info example again. Listing 5.4 shows a simple API for