Developing Large Web Applications- P22

Chia sẻ: Cong Thanh | Ngày: | Loại File: PDF | Số trang:10

0
35
lượt xem
3
download

Developing Large Web Applications- P22

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Developing Large Web Applications- P22:This book presents a number of techniques for applying established practices of good software engineering to web development—that is, development primarily using the disparate technologies of HTML, CSS, JavaScript, and server-side scripting languages. Whereas there are many books on how to use languages, how to use libraries, and how to approach software engineering, this is the first book to codify many of the techniques it presents. These techniques will make the components of your own web applications more reusable, maintainable, and reliable....

Chủ đề:
Lưu

Nội dung Text: Developing Large Web Applications- P22

  1. // Do what is needed when the Ajax call returns on a failure. } } ); POST The following method executes an Ajax POST request with jQuery. The parame- ters for the method are the same as described for GET except you set the type member to POST: jQuery.ajax ( { url: "service.php", type: "POST", timeout: 5000, data: { "key1": "val1", "key2": "val2", ... }, dataType: "json", success: function(data) { // Do what is needed when the Ajax call returns successfully. }, error: function(xhr, text, error) { // Do what is needed when the Ajax call returns on a failure. } } ); Ajax with Prototype Prototype is one of the earliest of the JavaScript libraries to support Ajax. You can download the library and read its complete documentation at http://www.prototypejs .org: GET The following method executes an Ajax GET request with Prototype. The method accepts two parameters: the destination for the request and an object whose most common members are shown below. In the handler specified by onSuccess, you access transport.responseText for responses using plain text. For XML responses, transport.responseXML will have been populated with a DOM that you can access with JavaScript DOM methods. For JSON responses, the transport.responseJSON member will have been populated with the JavaScript ob- ject that is the result of the evaluated response text. You specify the query param- eters for the GET as an object in the parameters member: In the Browser | 191
  2. Ajax.Request ( "service.php", { method: "get", parameters: { "key1": "val1", "key2": "val2", ... }, onSuccess: function(transport) { // Do what is needed when the Ajax call returns successfully. }, onFailure: function(transport) { // Do what is needed when the Ajax call returns on a failure. } } ); POST The following method executes an Ajax POST request with Prototype. The parameters for the method are the same as described for GET except you set the method member to post: Ajax.Request ( "service.php", { method: "post", parameters: { "key1": "val1", "key2": "val2", ... }, onSuccess: function(transport) { // Do what is needed when the Ajax call returns successfully. }, onFailure: function(transport) { // Do what is needed when the Ajax call returns on a failure. } } ); Ajax with YUI The YUI library was developed at Yahoo! for use both within Yahoo! and by the world’s web development community. You can download the library and read its complete documentation at http://developer.yahoo.com/yui. 192 | Chapter 8: Large-Scale Ajax
  3. As this book was being completed, YUI 3 was in beta development. The information below pertains to versions prior to this. One of the big dif- ferences between YUI 2 and YUI 3 is the YUI object, which places YUI 3 features in their own namespace. This lets you transition from YUI 2 to YUI 3 without having to change all your code at once. GET The following method executes an Ajax GET request using the YUI Connection Manager. The method accepts three parameters: the request type, the destination for the request, and an object whose most common members are shown below. In the handler specified by success, you access o.responseText for responses in plain text. For XML responses, o.responseXML will have been populated with a DOM that you can access with JavaScript DOM methods. For JSON, you need to evaluate the result in o.responseText yourself. The argument member is used to pass what- ever arguments you’d like to the handler methods. The timeout member is meas- ured in milliseconds: YAHOO.util.Connect.asyncRequest ( "GET", "service.php?key1=val1&key2=val2...", { success: function(o) { // Do what is needed when the Ajax call returns successfully. }, failure: function(o) { // Do what is needed when the Ajax call returns on a failure. }, timeout: 5000, argument: { key1: val1, key2: val2, ... } } ); POST The following method executes an Ajax POST request using the YUI Connection Manager. The parameters for the method are the same as described for GET except you set the first parameter to POST and add a fourth parameter containing a string of key-value pairs for the POST data: YAHOO.util.Connect.asyncRequest ( "POST", "service.php", In the Browser | 193
  4. { success: function(o) { // Do what is needed when the Ajax call returns successfully. }, failure: function(o) { // Do what is needed when the Ajax call returns on a failure. }, timeout: 5000, argument: { key1: val1, key2: val2, ... } }, "key1=val1&key2=val2..." ); On the Server Once an Ajax request is executed in the browser, it’s up to the server at the other end of the connection to handle the request. This section covers three important issues in writing the server’s side of the transaction: choosing a data format, using a server proxy, and applying techniques that promote modularity. Exchange Formats The primary formats used to send data in Ajax responses are plain text, XML, and JSON. Of course, whichever format you choose, the JavaScript that you provide to handle responses must be prepared to work with that format, regardless of whether the library detects the format automatically or requires you to specify the format explicitly. In this section, we explore the various formats for data returned by the server and look at how to work with each of them in PHP. Plain text Ajax responses in plain text are simply strings returned by the server. Generally, a response from the server using plain text is not very useful, because it’s largely un- structured. For anything but the simplest requests, this becomes unnecessarily difficult to deal with in the browser. Example 8-3 illustrates generating a plain-text response to an Ajax request in PHP. Example 8-3. Returning an Ajax response in plain text using PHP
  5. // Assemble whatever data is needed to form the appropriate response. ... $text =
  6. // For Ajax data that is very dynamic (which is often the case), you // can set Expires: 0 to invalidate cached copies in future requests. header("Expires: 0"); // Send the XML response. print($xml); ?> JSON Ajax responses in JSON are also highly structured; however, since JSON is actually nothing more than just the normal JavaScript syntax for object literals, and a JavaScript object is exactly what we need in the browser, JSON is a great fit for Ajax. When you receive a JSON response in the browser, you evaluate it using json_parse (if the library hasn’t done so already for you). After this, you access the data just like any other Java- Script object. Example 8-5 illustrates generating a JSON response to an Ajax request in PHP. You can find more about transforming a PHP data structure to JSON in Chap- ter 6. Example 8-5. Returning an Ajax response in JSON using PHP
  7. Server Proxies When you specify the destination for an Ajax request, it’s critical to remember that the destination must be on the same server that served the original page. In fact, some browsers will not allow you to specify a hostname within the destination at all, even if it’s the same as the originating server. As a result, avoid the usual http://hostname prefix with Ajax URLs. This same-origin policy prevents a type of security issue known as cross-site scripting (XSS), wherein code is injected by a malicious visitor into a page viewed by another visitor, unbeknownst to the initial visitor. Without such a policy for Ajax requests, malicious code could cause visitors of one page to interact unknowingly with an entirely different server. The issue is especially insidious for Ajax requests because they usually take place quietly behind the scenes. Fortunately for benevolent developers, there is a safe and easy way to have Ajax requests handled by a different server from the one that sent the page: place a server proxy on the originating server through which all Ajax requests pass (i.e., you use the path of the proxy in the requests) before being routed to their true destination. This is permitted because requests first must pass through a server presumably under your control (the original server). If visitors trust your site, the assumption is that they are willing to trust other servers with whom you are communicating. Of course, others may contact your proxy server directly to use it as a pass-through. As a result, in many situations you’ll want to examine who is making each request to determine whether or not it should be allowed to utilize the proxy. Example 8-6 is a server proxy for Ajax requests written using cURL in PHP. Example 8-6. A server proxy for Ajax requests
  8. $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, false); // Set the last value to true to return the output rather than echo it. curl_setopt($ch, CURLOPT_RETURNTRANSFER, false); header("Content-Type: application/json"); curl_exec($ch); curl_close($ch); ?> Modular Ajax As the amount of data that you need to manage for an Ajax application increases, so does the need to have good techniques to manage the complexity on the server. For- tunately, the techniques we presented using data managers in Chapter 6 also work well when managing data for Ajax requests. Recall from Chapter 6 that a data manager is an object that abstracts and encapsulates access to a specific set of data. Its purpose is to provide a well-defined, consistent in- terface by which you can get and set data in the backend, and to create a clear structure for the data itself. Chapter 6 also demonstrates how to combine and extend data man- agers using inheritance or aggregation. Recall that because a data manager is an object, anywhere you need to get the data it manages, you simply instantiate the data manager and call its get_data method. You can do this for Ajax, too. Since data managers return data in associative arrays in PHP, one additional step that you need to perform for Ajax requests is to transform the data into a format suitable for Ajax responses. This is easy if the desired format is JSON, since all you need to do is pass the data structure returned by the data manager to json_encode. For XML, the process is not so simple. Because the steps required to transform data to XML are usually specific to the data itself, it often makes sense to encapsulate the support for this directly within the data manager and enable it with a parameter as you need it. At times, you may want data marked up in HTML on the server. In this case, you can return the HTML within a member of a JSON object. Then, within the browser, insert it into the DOM using the innerHTML member of the node that you wish to make its parent. This approach may be beneficial when changes to the DOM resulting from an Ajax request are fairly complicated and you already have a lot of code on the server to construct the HTML. Rather than writing the code again in JavaScript, you can use the existing server code. Also, multiple calls to DOM methods in JavaScript, depending on the number and what they do, may result in slower performance than letting the browser rebuild the DOM for you after setting an element’s innerHTML member. Example 8-7 presents an example of an Ajax service that uses a data manager to return data for new car listings in the JSON format. The data manager follows the practices 198 | Chapter 8: Large-Scale Ajax
  9. outlined for data managers in Chapter 6. For example, it uses the new_car_listings member to keep the inputs and outputs for the data manager uniquely identifiable should there be multiple data managers in use. The example first sets up the arguments for NewCarListingsDataManager, then calls the data manager’s get_data method to pop- ulate $load_data. Once this method returns, it uses json_encode to convert the data in $load_data to JSON. Example 8-7. Handling an Ajax request with a data manager
  10. // Set the content type to inform that we're sending a JSON response. header("Content-Type: application/json"); // An Expires header set to 0 eliminates caching for future requests. header("Expires: 0"); // Return the JSON data. print($json); ?> MVC and Ajax Even with the help of Ajax libraries in the browser, large Ajax applications often have to manage complicated interactions. For example, changes to a single data source often require coordinated updates to several components in the user interface. In addition, the relationships between components in the user interface and their data sources may change over the lifetime of the application. MVC (Model-View-Controller) is a design pattern that can help address these issues. It does this by defining a system of distinct, loosely-coupled components: models, views, and controllers. Models are responsible for managing data, views are responsible for managing various presentations of the data, and controllers are responsible for controlling how the models and views change. In this section, we explore how MVC can help make the complexities of a large Ajax application more manageable. In the process, we’ll also observe more of the Ajax op- erations presented earlier in action. MVC is based on another design pattern, Publisher-Subscriber. The main idea behind Publisher-Subscriber is that a publisher maintains a list of subscribers that should be notified whenever something in the publisher changes. Publishers normally implement at least three methods: subscribe, unsubscribe, and notify. Subscribers call the sub scribe method to register for notifications; subscribers call the unsubscribe method to tell publishers that they no longer want the notifications; and the publisher itself calls the notify method whenever the publisher needs to notify its list of subscribers about a change. The main method that subscribers implement is update. The publisher calls the update method within notify to give a subscriber the chance to update itself about a data change. In the context of Publisher-Subscriber, models are publishers and views are subscrib- ers. As publishers, models manage data and notify subscribed views whenever changes happen in the model. As subscribers, views subscribe to models and update the pre- sentations they manage whenever they are notified by the models about changes to their data. The remarkable accomplishment of MVC, which it derives from Publisher- Subscriber, is that every time the data for a model changes, the views update themselves automatically. Furthermore, components responsible for the data and the presenta- tions are loosely coupled—that is, one doesn’t need to know about the other, so they are easier to maintain over an application’s lifetime. 200 | Chapter 8: Large-Scale Ajax
Đồng bộ tài khoản