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















 
 
 




 
 
 
 