AJAX模式與最佳實踐
第三章 內容分塊模式
3.1 目的
內容分塊模式使得增量地建立HTML頁面成爲可能,因此允許分佈式的HTML頁面邏輯部分存在,並且用戶能決定加載內容的時間和邏輯。
3.2 動機
在Web設計早期階段,HTML內容設計者創建的是一些不完整的文檔,通過文檔鏈接使它們完整。完整的文檔是文檔結構樹中所有頁面的總和。
思考下邊的例子:利用Web,你可以把大量雜誌中的文章粘貼到一起,不用以一種連續的方式來完成一本書的內容。但不想雜誌那樣,需要你一頁接一頁的翻看;Web允許你點擊鏈接跳轉到不同內容。隨着時間推移,Web站點已從分佈的Web結構轉變成有嚴格層次的獨立結構。
圖3-1描述了一個嚴格層次的獨立的Web站點例子。
在圖3-1中,Web站點被分成兩個區域:藍色背景的導航區域和棕色背景的內容區域。當用戶點擊導航鏈接的時候,內容就會隨之改變。但問題是整個頁面被重新加載,即使用戶只關心棕色背景的內容區域。一種不是很好的解決方式就是使用HTML frame,那麼導航區域是一個frame,內容區域是一個frame。當點擊導航區域的鏈接時,就只有內容區域frame被更改。然而,儘管frame可以解決獨立加載內容的問題,但從導航和用戶接口來看是有問題的。因此Web站點漸漸不使用frame了。
理想情況下,網站開發者想要的只是改變需要更新的內容,而不需要更新的不需要改動。畢竟,不涉及的內容仍然一樣起作用。
目標內容 |
導航欄 |
圖3-1嚴格層狀結構的Web站點
3.3 適用性
在以下情況下使用內容分快模式:
l 由於網站的特性,無法知道HTML頁面真正的樣子。如圖3-1,有一個藍色背景的導航區域和一個棕色背景的內容區域。每一個區域的內容都是未知的,但存放內容的區域是已知的。
l 要下載的內容量太大並且用戶等候過長時間。例如,進行一次搜索,將找到的所有元素收集起來成爲結果集,這樣做法不好,因爲用戶需要等很長時間。一種更好的方式是顯示當前找到的內容同時繼續搜索。
l 要顯示的內容是不相關的。雅虎、MSN和Excite都是並行顯示不相關內容的門戶應用。如果內容生成爲一個單獨的HTML頁面,那麼服務端邏輯就不得不包含大量的判定數據塊以確認內容是否需要加載。一種更好的方法是考慮將內容的每一塊作爲一個分離的片斷,然後單獨加載。
3.4 關聯模式
內容分塊模式是任何Ajax應用的核心模式,甚至可以認爲內容分塊模式是絕配Ajax應用的。即便如此,區別並定義內容分塊模式概念仍然很必要。內容分塊模式的獨特性在於它總是遵照同一過程:產生事件,請求,響應和分塊注入。書中其他模式也很相似,但與之相反的是如發送一個請求,並不是得到一個及時的響應(例如,持久通信模式)。
3.5 架構
內容分塊模式的架構相對簡單些。客戶端訪問URL,服務器端返回由客戶端接收和處理的內容。內容分塊模式的實現一般按照如下步驟:
1.點擊“按鈕”或加載HTML頁面後,生成相應的事件;
2.事件調用一個方法,這個方法負責創建要發送請求給服務器的URL;
3.服務器端接收到請求並聯合請求內容作爲響應返回給客戶端;
4.客戶端收到回覆,並且將其注入到HTML頁面中。
3.5.1 在Web應用中的執行順序
如前面圖3-1,Web站點的嚴格分層結構並不是很糟。至於HTML,這種嚴格其結果是一步到位的生成內容,這種方式會導致很多問題。傳統應用正如圖 3-2那樣沒有此種方式的功能。
圖3-2傳統客戶端應用
在圖3-2中,RealPlayer是一個將新的HTML類型技術和傳統界面元素混合的傳統客戶端應用例子。點擊“Burn Your CD”按鈕,RealPlayer就播放CD,但不會影響此應用上半部分正在播放的廣告。與廣告關聯的邏輯和播放CD關聯的邏輯是獨立的。不同邏輯片斷髮生在同一個窗口中。
圖3-3把圖3-1的Web應用分成了多個不同的邏輯片斷。
<Get Content 2 #>
|
<Get Content 1 #>
|
圖3-3Web站點體系結構
如圖3-3,原始HTML頁面中存在多個鏈接,如到例子中博客和文章等內容的鏈接。例子中的內容有兩個執行模塊:Get Navagition和Get Content(1,2)。用於產生Get Content1的邏輯和用於產生Get Content2的邏輯是不同的。在生成HTML頁面時,當執行Get Content1和Get Content2任何一個,Get Navagition的邏輯都要執行。這意味着邏輯Get Navagition會被執行多次,每次都產生相同的數據。一些讀者可能會認爲Get Navagition產生的是不同的數據(如:打開不同的文件夾),但實際上是以不同格式方式存在的相同數據。簡而言之,應該避免產生內在的數據冗餘。
解決方案是使用分散邏輯,從而通過類似圖3-4的架構來生成HTML頁面。
<Get Content 2 #>
|
<Get Content 1 #>
|
圖3-4改進的Web站點結構
在圖3-4中,HTML頁面是多個服務端邏輯片斷結合的結果。當HTML頁面主要的輪廓加載後,XMLHttpRequest對象會重新獲得Get Navigation、Get Content 1和Get Content 2等內容塊。什麼時候如何獲得單個的內容塊依賴於內容塊產生的事件和鏈接。每一個內容塊是需要XMLHttpRequest類型對象處理的單獨請求。
這裏主張的架構有以下優勢:
l 客戶端僅僅下載必須的內容,不必再獲得已經沒有用的內容塊;
l 結構被分成不同的代碼塊,能夠在不同環境下動態組合;
l 結構類似一個傳統的客戶端,在客戶端只適合於操縱事件的那些元素;
l 因爲對於獲得內容數據塊的父HTML頁面來說,生成的代碼塊代表頁面外觀,所以整個外觀看起來不會受到影響。
如圖3-4解釋了內容分塊模式名字的由來:一個單獨的HTML頁面是許多內容塊的累加,這些內容塊被單獨引用和加載。
3.5.2 定義內容塊中的內容
XMLHttpRequest對象引用的內容塊可以是任何客戶端和服務器端能理解的形式。無論服務器端發送什麼都必須是客戶端能理解的。如圖3-4,由於數據塊被直接注入到HTML頁面中,所以內容數據塊將會存在HTML中,儘管HTML不是服務器端收發內容的唯一格式。
本章中涉及了以下格式:
l HTML:服務器端直接發送HTML到客戶端。接收到的HTML不需要處理,直接注入到HTML頁面中。這是一個盲目的處理方法,因爲客戶端不知道HTML做了什麼,只知道將其注入到HTML的某段代碼中。直接注入HTML是一種非常安全和簡單的內容構建方式。客戶端不需要做任何處理,僅僅需要知道HTML內容的目的區域。如果需要處理,接收到的內容(如果是符合XML)將會作爲一個有效的實例對象模型。使用實例對象模型,就能手動操作接收到的HTML內容了。建議發送到客戶端的HTML內容應該符合XHTML(實現特定XML規範的HTML)格式或至少符合XML格式。
l 圖片:由於圖片是二進制格式的,且XMLHttpRequest對象不能處理二進制數據,所以直接發送圖片是不可能的。特別是圖片的引用都是被作爲HTML標籤注入到HTML文檔中的,導致加載遠程圖片。如果數據以Base64格式進行編碼和解碼,二進制數據就可以下載和引用了。然而,不推薦直接操作二進制數據,因爲使用此方式後會產生更多問題,比使用此方式解決的問題還要多。
l JavaScript:服務器端能夠發送JavaScript到客戶端,客戶端利用JavaScript中eval語句執行JavaScript;並且爲了更進一步的處理,客戶端能夠發送持久的JavaScript對象給服務器。執行任意JavaScript的第一感覺就是安全問題。這不是很特別的問題,因爲所有瀏覽器中JavaScript引擎都具有一樣的起源和沙箱機制。如果JavaScript引擎中存在bug,發送任意要執行的JavaScript會產生安全問題。如果需要動態執行和增加在加載HTML初始化頁面時沒有被加載的客戶端邏輯,發送JavaScript是適合的。在客戶端沒有意識到的情況下,這是一個增強客戶端功能的有效方法。舉個例子,HTML表單元素的驗證。由於不同的用戶有不同的確認方式,把所有確認方式都發送到客戶端是不想要的。解決方案就是讓用戶決定需要展現的HTML表單元素,並且動態下載作爲內容塊的表單元素驗證方式。但預先警告,發送的JavaScript數據塊會使應用系統對黑客開放。因此在使用此技術前請仔細考慮。
l XML:使用XML收發是首選方式。在客戶端能夠使用XML對象模型進行轉換和解析XML;或者使用可擴展的表單語言轉換庫,把XML轉換成其他對象,如HTML。首選XML的原因:XML是一項衆所周知的技術,且操縱XML的工具具有說明詳細、運行穩定等優點。XML是一項非常好的已確定的技術,使用此種技術,你不需要寫額外的代碼就能進行搜索、分段、分塊、持久和驗證。由於方括號和其他XML字符記號,所以有些人認爲XML很繁重。然而優勢是當服務器端應用產生XML時,能夠被基於Web瀏覽器和非GUI瀏覽器的客戶端處理。如何解析XML和處理什麼信息完全依賴於客戶端,只要客戶端能夠解析XML即可。使用XML應該靈活。貫穿全書,XML被廣泛使用且被作爲首要的數據交換格式。
還有其他的數據交換格式,如JavaScript對象註解(JSON)1。然而,選擇其他格式時,建議多考慮一下使用它們產生的後果。然而對我們當前的設計,有的並不適合。關於其它數據交換格式,對於我來說,它們不能提供一個像處理、查找、驗證和產生XML的一樣的強大開發環境。例如,使用XPath I不需要解析整個XML文檔,就可搜索XML中的特定元素。也承認在某些情況下,XML的性能不如JSON。對於很多讀者,並不關心XML的差異,確定他們不需要這些,JSON可能會是更好的技術。然而在本書的其他章節模式內,並沒有包括其他技術,如JSON。
既然已經瞭解了此結構,後面你將會看到一些實現此結構的實例。