Ajax必備 開發須思考的基本原則
通過 AJAX,您的 JavaScript 可使用 JavaScript 的 XMLHttpRequest 對象來直接與服務器進行通信。通過這個對象,您的 JavaScript 可在不重載頁面的情況與 Web 服務器交換數據。下面介紹Ajax開發時需要思考的幾個基本原則
我們用到的很多框架中都已經固化了基于頁面的傳統應用模式,同時這些應用模式也已經深深進入了我們的思想中。我們花幾分鐘來揭示出哪些核心概念是我們需要重新思考的,以及如何從Ajax的角度來重新思考。
一、瀏覽器中的是應用而不是內容
在傳統的基于頁面的Web應用中,瀏覽器扮演著啞終端1的角色。它對用戶處于操作流程哪一階段一無所知。這些信息全部都保存在服務器上,確切地說,就是在用戶會話上。時至今日,服務器端的用戶會話早已是司空見慣。如果你使用Java 或者.NET 編程,服務器端的用戶會話更是標準API 的一部分——還有Request、Response、MIME 類型——沒有了它們簡直不可想象。
當用戶登錄或者以其他方式初始化一個會話時,系統會創建幾個服務器端的對象。例如,電子商務類型的網站需要創建表示購物車以及用戶身份證明的對象。同時將瀏覽器站點的首頁呈現給用戶,這個HTML 標記的數據流由模板文件以及特定于該用戶的數據和內容(例如該用戶最近瀏覽的商品列表)組成。
用戶每次和服務器交互,都會獲得另一個文檔。在這個文檔中,除了特定于該用戶的數據以外,包含的其他模板文件和數據都是相同的。瀏覽器總是忠實地丟棄掉老的文檔,顯示新的文檔,因為它是啞終端,而且也不知道還可以做些什么。
當用戶選擇退出或者關閉瀏覽器的時候,應用退出,會話消失。這個時候持久層會把用戶下次登錄后需要顯示的信息存儲起來。Ajax則不同,它把一部分應用邏輯從服務器端移到了瀏覽器端。
傳統Web應用的生命周期。用戶和應用會話的所有狀態都保留在Web服務器上。用戶在會話中看到的是一系列的頁面,每次頁面切換都不可避免地要到服務器上走一個來回。
Ajax應用的生命周期。用戶登錄后,服務器交付一個客戶端應用給瀏覽器。這個應用可以獨立處理很多的用戶交互,對于自己無法獨立處理的交互,應用會以后臺方式發送請求給服務器,而不會打斷用戶的操作流程。
用戶登錄的時候,服務器交付給瀏覽器一個復雜得多的文檔,其中包含大量的JavaScript代碼。這個文檔將會在整個會話的生命周期內與用戶相伴。在這一過程中,隨著用戶與其交互,它的外觀可能會發生相當大的變化。它知道如何響應用戶的輸入,能夠決定對于這些請求,是自行處理還是傳遞給Web服務器(Web服務器再去訪問數據庫或者其他資源),或者通過兩者結合的方式進行處理。因為這個文檔在整個用戶會話中都存在,所以它可以保存狀態1。例如,購物車的內容可以保存在瀏覽器中而不是服務器的會話中。
二、服務器交付的是數據而不是內容
我們已經提到,在傳統的Web應用中,服務器在每個步驟都需要把模板文件、內容和數據混合發送給瀏覽器。但實際上,當向購物車中添加一件物品的時候,服務器真正需要響應的僅僅是更新一下購物車中的價格。
基于Ajax的購物車可以向服務器發起一個異步請求來完成這件事,這樣做顯得更聰明。模板文件、導航列表和頁面布局上的其他部分已經隨著初始頁面發送給了瀏覽器,服務器無需重發,以后每次只需要發送相關的數據就可以了。Ajax應用可以通過多種方式來做這件事情。例如,返回一段JavaScript代碼、一段純文本或者一小段XML文檔。這些方式各自的優缺點,我們將留到第5 章再詳細考察。但是,毫無疑問的是,無論返回數據采用何種格式,這些方式所傳輸的數據量都要比傳統的Web應用中一股腦返回一個大雜燴的方式少得多。
在Ajax應用中,網絡的通信流量主要是集中在加載的前期,無論如何,用戶登錄后是需要一次性地將一個大而復雜的客戶端交付給瀏覽器。但是在此之后,與服務器的通信則會有效率得多。對于瞬態應用來說,積累起來的通信流量要比以前的基于頁面的Web應用少很多。與此同時,平均的交互次數則有所增加。整體而言,Ajax應用的帶寬消耗要比傳統的Web應用低一些。
三、用戶交互變得流暢而連續
瀏覽器提供了兩種輸入機制:超鏈接和HTML 表單。超鏈接可以在服務器上創建,并預加載指向動態服務器頁面或者servlet 的CGI 參數??梢杂脠D片或者CSS(層疊樣式表)來裝飾超鏈接,并且當鼠標停在上面時還可以提供基本的反饋。經過合理設計,超鏈接可以變成一個很有想像力的UI 組件。表單則提供了桌面應用的一組基礎UI 組件:輸入文本框、單選按鈕和多選按鈕,還有下拉列表。但仍然缺少很多有用的UI 組件,例如,沒有可用的樹控件、可編輯的柵格、組合輸入框等。表單像超鏈接一樣,也指向服務器的一個URL 地址。
超鏈接和表單也可以指向JavaScript函數。這一技術通常用在將數據提交給服務器之前對表單輸入進行簡單的校驗,如檢驗是否有空值,數值是否越界等等。這些JavaScript函數的生存期和頁面本身是一致的,當頁面提交之后,這些函數也就不存在了。
當一個頁面已提交而下一個頁面還沒有顯示出來的時候,用戶實際上處于沒人管的狀態。老的頁面還要顯示一會兒,瀏覽器甚至還會允許用戶點擊一些鏈接。但這些點擊可能會導致一些不可預料的結果,甚至破壞服務器端會話的狀態。用戶通常應該等到頁面刷新完成,當然也可以選擇在刷新完成之前就在新頁面上做一些操作。例如,當頁面只顯示了一部分時從中選擇一條褲子放進購物車不大可能會造成什么破壞(例如,不會修改頂級的服裝分類:男裝、女裝、童裝、配飾)。我們繼續看這個購物車的例子。Ajax的購物車是通過異步方式發送數據的,用戶可以很快地把東西拖進來,就像點擊一樣快。只要客戶端購物車的代碼足夠健壯,它可以很輕松地處理這樣的負載,而用戶則可以繼續做他想做的事。
要知道,在服務器端并沒有一個真正的購物車等著裝東西,只有會話中的一個對象而已。購物的時候,用戶并不想知道會話對象,購物車對于用戶而言是一個較恰當的比喻,用現實世界中熟悉的概念來描述這里發生的事情。對于用戶來說,如果強迫他們去理解計算機領域中的術語,只會讓他們遠離網站。等待頁面的刷新,一下子就把用戶從愉快的使用體驗中拽了出來,讓他感覺到自己所面對的只不過是一臺冰冷的機器罷了。使用Ajax來實現這些應用則可以避免這些令人不快的體驗。當然了,在這個例子中的購物只是一個瞬態活動。考察一下其他的業務領域,例如,一個業務量很大的幫助中心或者一項復雜的工程任務,如果因為需要等待頁面刷新,而將工作流程打斷幾秒鐘,那肯定是不可接受的。
Ajax的另一個好處是,我們可以對豐富的用戶操作事件進行捕獲。類似于拖拽這樣的復雜UI 概念也不再是遙不可及的。這使得Web應用的UI 體驗可以全面提升到近乎與桌面應用的UI組件相媲美的高度。從可用性的角度來看,這很重要,不僅僅是因為它釋放了我們的想象力,而且也是因為它可以將用戶交互和服務器端的請求更加充分地混合起來。在傳統的Web應用中,與服務器交互需要點擊超鏈接或者提交表單,然后等待頁面的刷新,這打斷了用戶的工作流程。與之相對應的是,讓服務器響應鼠標移動、拖拽或者鍵盤輸入這樣的用戶事件,也就是說,服務器在用戶身邊為用戶服務,而不是擋在用戶前面,打斷他的操作。
google Suggest(www.google.com/webhp?complete=1)就是這樣一個簡單的但是很有說服力的例子。當用戶在搜索框鍵入一些字符的時候,應用從服務器取回與用戶已鍵入字符串相似的搜索條目(根據全世界其他人的搜索),并且顯示在輸入框下方的下拉列表中。
四、有紀律的嚴肅編程
現在傳統的Web應用有時候也會用到JavaScript,不過主要是用來給頁面添加一些花哨的東西?;陧撁娴哪P褪沟眠@樣的增強沒有辦法更進一步,限制了用戶可以得到的更加理想的交互。這種類似于第22條軍規的狀況,使得JavaScript很不公平地獲得了一種瑣碎的、自由散漫的編程語言的名聲,為那些嚴肅的開發者1所不屑。
為Ajax應用編程的情況則完全不同。提交給用戶運行的應用將會一直運行直到用戶關閉程序為止。不崩潰,不變慢,也沒有內存泄漏之類的毛病。如果我們的產品定位于獨占式應用的市場,這還意味著很多小時的密集使用。要達到這個目標,當然需要高性能的、可維護的代碼,這與服務器端應用的要求是一致的。
相比之下,Ajax的代碼庫會比傳統的Web應用大很多。對代碼庫進行良好的組織是非常重要的。編寫代碼不再是單個開發者的職責,而是整個團隊來參與。可維護性、分離關注點、共同的編程風格以及設計模式,這些都是需要考慮的問題。
從某個角度來看,Ajax應用就是用戶所使用的一塊復雜的代碼,它需要高效地與服務器進行通信。它顯然來源于傳統的基于頁面的Web應用,但是它們之間的相似性也僅限于此,兩者之間的差別就像是木馬輪和現代自行車之間的差別。在腦海中要記得它們之間的這些差別,因為只有這樣才能創造出真正引人注目的Web應用。
原文地址:http://www.yiiyaa.net/
【編輯推薦】