亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

AJAX 簡(jiǎn)介及入門實(shí)例

 更新時(shí)間:2009年07月23日 23:20:37   作者:  
最近在學(xué)校參加暑期實(shí)習(xí),參與的是一個(gè)社交網(wǎng)站項(xiàng)目,學(xué)長(zhǎng)那邊分配給的任務(wù)是前端開(kāi)發(fā),需要學(xué)習(xí)AJAX技術(shù)。

對(duì)于一個(gè)像我一樣剛剛接觸Web開(kāi)發(fā)且無(wú)多少實(shí)際項(xiàng)目經(jīng)驗(yàn)的新手而言,AJAX技術(shù)顯得復(fù)雜而又深?yuàn)W。經(jīng)過(guò)兩天的baidu、google,我對(duì)AJAX的基本原理有了一個(gè)大致的認(rèn)識(shí),在此總結(jié)一下。

1. 什么是AJAX?
AJAX全稱是異步的JavaScript和XML,是Asynchronous JavaScript and XML的縮寫(xiě)。AJAX技術(shù)用于創(chuàng)建交互式網(wǎng)頁(yè)應(yīng)用的網(wǎng)站開(kāi)發(fā),至于何為異步,后文會(huì)有解釋。

1.1 桌面應(yīng)用程序和Web應(yīng)用程序
在詳細(xì)討論AJAX技術(shù)之前,需要先知道AJAX技術(shù)究竟是用來(lái)做什么工作的。目前,編寫(xiě)應(yīng)用程序總共有兩種基本類型:

桌面應(yīng)用程序 (Desktop Application)
Web應(yīng)用程序 (Web Application)
桌面應(yīng)用程序可以從互聯(lián)網(wǎng)或者以CD方式獲得,需要運(yùn)行在桌面計(jì)算機(jī)上,例如我們常見(jiàn)的一些PC軟件。Web應(yīng)用程序與之不同,Web應(yīng)用程序師運(yùn)行在某處的Web服務(wù)器上的,因此需要通過(guò)Web瀏覽器去訪問(wèn)這樣的應(yīng)用程序。

不過(guò),比這些應(yīng)用程序的代碼運(yùn)行在何處更為重要的是,應(yīng)用程序如何運(yùn)轉(zhuǎn)以及如何與其進(jìn)行交互。桌面應(yīng)用程序一般較快,并且擁有漂亮的用戶界面和非凡的動(dòng)態(tài)性,可以單擊、選擇、打開(kāi)菜單和子菜單、到處巡游,基本不需要等待;另一方面,Web應(yīng)用程序(比如Amazon.com 和eBay)提供了桌面程序不能實(shí)現(xiàn)的服務(wù)。然而,伴隨著Web的強(qiáng)大而出現(xiàn)的是等待,等待服務(wù)器的響應(yīng),等待屏幕刷新,等待請(qǐng)求返回和生成新的界面。

AJAX的出現(xiàn),就是為了緩解Web應(yīng)用中與桌面應(yīng)用相比中的等待這一問(wèn)題。

1.2 AJAX - 老技術(shù),新面孔
AJAX技術(shù)其實(shí)不是什么新技術(shù),而是其他幾種已存在技術(shù)的整合。

AJAX應(yīng)用程序使用到以下基本技術(shù):

使用HTML和CSS來(lái)建立Web表單并表示網(wǎng)頁(yè)信息;
使用JavaScript來(lái)操作DOM(Document Object Model)來(lái)進(jìn)行動(dòng)態(tài)顯示及交互;
使用XMLHttpRequest對(duì)象與Web服務(wù)器進(jìn)行異步數(shù)據(jù)交換;
使用XML進(jìn)行數(shù)據(jù)交換及相關(guān)操作;
使用JavaScript將所有東西綁定在一起。
我們來(lái)進(jìn)一步分析這些技術(shù)的職責(zé)。目前我只要熟悉這些組件和技術(shù)就可以了。對(duì)這些代碼越熟悉,就越容易從對(duì)這些技術(shù)的零散了解轉(zhuǎn)變到真正把握這些技術(shù)(同時(shí)也真正打開(kāi)了 Web 應(yīng)用程序開(kāi)發(fā)的大門)。

XMLHttpRequest對(duì)象

要了解的一個(gè)對(duì)象可能對(duì)您來(lái)說(shuō)也是最陌生的,即 XMLHttpRequest。這是一個(gè) JavaScript 對(duì)象,創(chuàng)建該對(duì)象很簡(jiǎn)單,如清單 1 所示。

清單 1. 創(chuàng)建新的 XMLHttpRequest 對(duì)象

復(fù)制代碼 代碼如下:

<script language="javascript" type="text/javascript">
<!--
var xmlHttp = new XMLHttpRequest();
// -->
</script>

以后將進(jìn)一步學(xué)習(xí)這個(gè)對(duì)象,現(xiàn)在要知道這是處理所有服務(wù)器通信的對(duì)象。繼續(xù)閱讀之前,先停下來(lái)想一想:通過(guò) XMLHttpRequest 對(duì)象與服務(wù)器進(jìn)行對(duì)話的是 JavaScript 技術(shù)。這不是一般的應(yīng)用程序流,這恰恰是 Ajax 的強(qiáng)大功能的來(lái)源。
在一般的 Web 應(yīng)用程序中,用戶填寫(xiě)表單字段并單擊提交按鈕。然后整個(gè)表單發(fā)送到服務(wù)器,服務(wù)器將它轉(zhuǎn)發(fā)給處理表單的腳本(通常是 PHP 或 Java,也可能是 CGI 進(jìn)程或者類似的東西),腳本執(zhí)行完成后再發(fā)送回全新的頁(yè)面。該頁(yè)面可能是帶有已經(jīng)填充某些數(shù)據(jù)的新表單的 HTML,也可能是確認(rèn)頁(yè)面,或者是具有根據(jù)原來(lái)表單中輸入數(shù)據(jù)選擇的某些選項(xiàng)的頁(yè)面。當(dāng)然,在服務(wù)器上的腳本或程序處理和返回新表單時(shí)用戶必須等待。屏幕變成一片空白,等到服務(wù)器返回?cái)?shù)據(jù)后再重新繪制。這就是交互性差的原因,用戶得不到立即反饋,因此感覺(jué)不同于桌面應(yīng)用程序。

Ajax 基本上就是把 JavaScript 技術(shù)和 XMLHttpRequest 對(duì)象放在 Web 表單和服務(wù)器之間。當(dāng)用戶填寫(xiě)表單時(shí),數(shù)據(jù)發(fā)送給一些 JavaScript 代碼而不是直接發(fā)送給服務(wù)器。相反,JavaScript 代碼捕獲表單數(shù)據(jù)并向服務(wù)器發(fā)送請(qǐng)求。同時(shí)用戶屏幕上的表單也不會(huì)閃爍、消失或延遲。換句話說(shuō),JavaScript 代碼在幕后發(fā)送請(qǐng)求,用戶甚至不知道請(qǐng)求的發(fā)出。更好的是,請(qǐng)求是異步發(fā)送的,就是說(shuō) JavaScript 代碼(和用戶)不用等待服務(wù)器的響應(yīng)。因此用戶可以繼續(xù)輸入數(shù)據(jù)、滾動(dòng)屏幕和使用應(yīng)用程序。

然后,服務(wù)器將數(shù)據(jù)返回 JavaScript 代碼(仍然在 Web 表單中),后者決定如何處理這些數(shù)據(jù)。它可以迅速更新表單數(shù)據(jù),讓人感覺(jué)應(yīng)用程序是立即完成的,表單沒(méi)有提交或刷新而用戶得到了新數(shù)據(jù)。JavaScript 代碼甚至可以對(duì)收到的數(shù)據(jù)執(zhí)行某種計(jì)算,再發(fā)送另一個(gè)請(qǐng)求,完全不需要用戶干預(yù)!這就是XMLHttpRequest 的強(qiáng)大之處。它可以根據(jù)需要自行與服務(wù)器進(jìn)行交互,用戶甚至可以完全不知道幕后發(fā)生的一切。結(jié)果就是類似于桌面應(yīng)用程序的動(dòng)態(tài)、快速響應(yīng)、高交互性的體驗(yàn),但是背后又擁有互聯(lián)網(wǎng)的全部強(qiáng)大力量。
加入一些 JavaScript
得到 XMLHttpRequest 的句柄后,其他的 JavaScript 代碼就非常簡(jiǎn)單了。事實(shí)上,我們將使用 JavaScript 代碼完成非?;镜娜蝿?wù):

獲取表單數(shù)據(jù):JavaScript 代碼很容易從 HTML 表單中抽取數(shù)據(jù)并發(fā)送到服務(wù)器。
修改表單上的數(shù)據(jù):更新表單也很簡(jiǎn)單,如設(shè)置字段值或者迅速替換圖像。
解析 HTML 和 XML:使用 JavaScript 代碼操縱 DOM,處理 HTML 表單服務(wù)器返回的 XML 數(shù)據(jù)的結(jié)構(gòu)。
對(duì)于前兩點(diǎn),需要非常熟悉 getElementById() 方法,如 清單 2 所示。

清單 2. 用 JavaScript 代碼捕獲和設(shè)置字段值
復(fù)制代碼 代碼如下:

// Get the value of the "phone" field and stuff it in a variable called phone
var phone = document.getElementById("phone").value;
// Set some values on a form using an array called response
document.getElementById("order").value = response[0];
document.getElementById("address").value = response[1];

這里沒(méi)有特別需要注意的地方,真是好極了!您應(yīng)該認(rèn)識(shí)到這里并沒(méi)有非常復(fù)雜的東西。只要掌握了 XMLHttpRequest,Ajax 應(yīng)用程序的其他部分就是如 清單 2 所示的簡(jiǎn)單 JavaScript 代碼了,混合有少量的 HTML。

2. AJAX的優(yōu)缺點(diǎn)是什么?
2.1 AJAX的優(yōu)點(diǎn)
使用AJAX最大的優(yōu)點(diǎn),就是能在不更新整個(gè)頁(yè)面的前提下維護(hù)數(shù)據(jù)。這使得Web應(yīng)用程序能更為迅捷得對(duì)用戶請(qǐng)求進(jìn)行反饋,提高了用戶體驗(yàn)的同時(shí),避免了在網(wǎng)絡(luò)上發(fā)送那些沒(méi)有改變過(guò)的信息。

傳統(tǒng)的Web應(yīng)用允許用戶端填寫(xiě)表單(form),當(dāng)送出表單時(shí)就向Web服務(wù)器發(fā)送一個(gè)請(qǐng)求。服務(wù)器接收并處理傳來(lái)的表單,然后送回一個(gè)新的網(wǎng)頁(yè),但這種做法浪費(fèi)了很多帶寬,因?yàn)椋涸谇昂髢蓚€(gè)處理后反饋的頁(yè)面匯總,大部分的HTML代碼往往是相同的。由于每次應(yīng)用的溝通都需要向服務(wù)器發(fā)送請(qǐng)求,應(yīng)用的回應(yīng)時(shí)間久依賴于服務(wù)器的響應(yīng)時(shí)間,這導(dǎo)致了用戶界面的回應(yīng)比本機(jī)應(yīng)用慢很多。

與此不同的是,AJAX應(yīng)用可以僅向服務(wù)器發(fā)送并取回必要的數(shù)據(jù),它使用SOAP或其它一些基于XML的頁(yè)面服務(wù)接口(界面),并在客戶端采用JavaScript處理來(lái)自服務(wù)器的回應(yīng)。因?yàn)樵诜?wù)器和瀏覽器之間交換的數(shù)據(jù)大量減少(大約只有原來(lái)的5%),結(jié)果我們就能看到回應(yīng)(服務(wù)器回應(yīng))更快的應(yīng)用(結(jié)果)。同時(shí)很多的處理工作可以在發(fā)出請(qǐng)求的客戶端機(jī)器上完成,所以Web服務(wù)器的處理時(shí)間也減少了。

2.2 AJAX的缺點(diǎn)
對(duì)應(yīng)于AJAX最主要的批評(píng)是:它可能破壞瀏覽器后退按鈕的正常行為。在動(dòng)態(tài)更新頁(yè)面的情況下,用戶無(wú)法回到前一個(gè)頁(yè)面的狀態(tài),這是因?yàn)闉g覽器僅能記下歷史記錄中的靜態(tài)頁(yè)面。一個(gè)被完整讀入的頁(yè)面與一個(gè)已經(jīng)被動(dòng)態(tài)修改過(guò)的頁(yè)面之間的差別非常微妙:用戶通常都希望單擊后退按鈕,就能夠取消他們的前一次操作,但是在AJAX頁(yè)面中,可能無(wú)法這樣做。不過(guò)開(kāi)發(fā)者已想出了種種辦法來(lái)解決這個(gè)問(wèn)題,當(dāng)中大多數(shù)都是在用戶單擊后退按鈕訪問(wèn)歷史記錄時(shí),通過(guò)建立或使用一個(gè)隱藏的IFRAME來(lái)重現(xiàn)頁(yè)面上的變更。(例如,當(dāng)用戶在Google Maps中單擊后退時(shí),它在一個(gè)隱藏的IFRAME中進(jìn)行搜索,然后將搜索結(jié)果反映到AJAX元素上,以便將應(yīng)用程序狀態(tài)恢復(fù)到當(dāng)時(shí)的狀態(tài)。)

另一個(gè)相關(guān)的觀點(diǎn)認(rèn)為,使用動(dòng)態(tài)頁(yè)面更新使得用戶難于將某個(gè)特定的狀態(tài)保存到收藏夾中。該問(wèn)題的解決方案也已出現(xiàn),大部分都使用URL片斷標(biāo)識(shí)符(通常被稱為錨點(diǎn),即URL中#后面的部分)來(lái)保持跟蹤,允許用戶回到指定的某個(gè)應(yīng)用程序狀態(tài)。(許多瀏覽器允許JavaScript動(dòng)態(tài)更新錨點(diǎn),這使得Ajax應(yīng)用程序能夠在更新顯示內(nèi)容的同時(shí)更新錨點(diǎn)。)這種解決方案也同時(shí)解決了許多關(guān)于不支持后退按鈕的爭(zhēng)論。

進(jìn)行AJAX開(kāi)發(fā)時(shí),網(wǎng)絡(luò)延遲——即用戶發(fā)出請(qǐng)求到服務(wù)器發(fā)出響應(yīng)之間的間隔——需要慎重考慮。不給予用戶明確的回應(yīng)、沒(méi)有恰當(dāng)?shù)念A(yù)讀數(shù)據(jù),或者對(duì)XMLHttpRequest的不恰當(dāng)處理,都會(huì)使用戶感到延遲,這是用戶不想看到的,也是他們無(wú)法理解的。通常的解決方案是,使用一個(gè)可視化的組件來(lái)告訴用戶系統(tǒng)正在進(jìn)行后臺(tái)操作并且正在讀取數(shù)據(jù)和內(nèi)容。

3. AJAX應(yīng)用的通用流程
3.1 創(chuàng)建request對(duì)象
有了上面的基礎(chǔ)知識(shí)后,我們來(lái)看看一些具體的例子。XMLHttpRequest 是 AJAX應(yīng)用程序的核心,而且對(duì)很多讀者來(lái)說(shuō)可能還比較陌生,我們就從這里開(kāi)始吧。從 清單 1 可以看出,創(chuàng)建和使用這個(gè)對(duì)象非常簡(jiǎn)單,不是嗎?等一等。

還記得幾年前的那些討厭的瀏覽器戰(zhàn)爭(zhēng)嗎?沒(méi)有一樣?xùn)|西在不同的瀏覽器上得到同樣的結(jié)果。不管您是否相信,這些戰(zhàn)爭(zhēng)仍然在繼續(xù),雖然規(guī)模較小。但令人遺憾的是,XMLHttpRequest 成了這場(chǎng)戰(zhàn)爭(zhēng)的犧牲品之一。因此獲得 XMLHttpRequest 對(duì)象可能需要采用不同的方法。下面我將詳細(xì)地進(jìn)行解釋。

使用 Microsoft 瀏覽器

Microsoft 瀏覽器 Internet Explorer 使用 MSXML 解析器處理 XML。因此如果編寫(xiě)的AJAX應(yīng)用程序要和 Internet Explorer 打交道,那么必須用一種特殊的方式創(chuàng)建對(duì)象。

但并不是這么簡(jiǎn)單。根據(jù) Internet Explorer 中安裝的 JavaScript 技術(shù)版本不同,MSXML 實(shí)際上有兩種不同的版本,因此必須對(duì)這兩種情況分別編寫(xiě)代碼。請(qǐng)參閱 清單 3,其中的代碼在 Microsoft 瀏覽器上創(chuàng)建了一個(gè) XMLHttpRequest。

清單 3. 在 Microsoft 瀏覽器上創(chuàng)建 XMLHttpRequest 對(duì)象
復(fù)制代碼 代碼如下:

var xmlHttp = false;
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
xmlHttp = false;
}
}

您對(duì)這些代碼可能還不完全理解,但沒(méi)有關(guān)系,現(xiàn)在只要牢牢記住其中的兩行代碼:

xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");

這兩行代碼基本上就是嘗試使用一個(gè)版本的 MSXML 創(chuàng)建對(duì)象,如果失敗則使用另一個(gè)版本創(chuàng)建該對(duì)象。不錯(cuò)吧?如果都不成功,則將 xmlHttp 變量設(shè)為 false,告訴您的代碼出現(xiàn)了問(wèn)題。如果出現(xiàn)這種情況,可能是因?yàn)榘惭b了非 Microsoft 瀏覽器,需要使用不同的代碼。

處理 Mozilla 和非 Microsoft 瀏覽器

如果選擇的瀏覽器不是 Internet Explorer,或者為非 Microsoft 瀏覽器編寫(xiě)代碼,就需要使用不同的代碼。事實(shí)上就是 清單 1 所示的一行簡(jiǎn)單代碼:

var xmlHttp = new XMLHttpRequest object;。

這行簡(jiǎn)單得多的代碼在 Mozilla、Firefox、Safari、Opera 以及基本上所有以任何形式或方式支持 Ajax 的非 Microsoft 瀏覽器中,創(chuàng)建了 XMLHttpRequest 對(duì)象。

綜合起來(lái)跨瀏覽器的通用方法

關(guān)鍵是要支持所有瀏覽器。誰(shuí)愿意編寫(xiě)一個(gè)只能用于 Internet Explorer 或者非 Microsoft 瀏覽器的應(yīng)用程序呢?或者更糟,要編寫(xiě)一個(gè)應(yīng)用程序兩次?當(dāng)然不!因此代碼要同時(shí)支持 Internet Explorer 和非 Microsoft 瀏覽器。清單 4 顯示了這樣的代碼。

清單 4. 以支持多種瀏覽器的方式創(chuàng)建 XMLHttpRequest 對(duì)象
復(fù)制代碼 代碼如下:

/* Create a new XMLHttpRequest object to talk to the Web server */
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e2) {
xmlHttp = false;
}
}
@end @*/
if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
xmlHttp = new XMLHttpRequest();
}

現(xiàn)在先不管那些注釋掉的奇怪符號(hào),如 @cc_on,這是特殊的 JavaScript 編譯器命令,將在下一期針對(duì) XMLHttpRequest 的文章中詳細(xì)討論。這段代碼的核心分為三步:

建立一個(gè)變量 xmlHttp 來(lái)引用即將創(chuàng)建的 XMLHttpRequest 對(duì)象。
嘗試在 Microsoft 瀏覽器中創(chuàng)建該對(duì)象:
嘗試使用 Msxml2.XMLHTTP 對(duì)象創(chuàng)建它。
如果失敗,再嘗試 Microsoft.XMLHTTP 對(duì)象。
如果仍然沒(méi)有建立 xmlHttp,則以非 Microsoft 的方式創(chuàng)建該對(duì)象。
最后,xmlHttp 應(yīng)該引用一個(gè)有效的 XMLHttpRequest 對(duì)象,無(wú)論運(yùn)行什么樣的瀏覽器。

3.2 AJAX技術(shù)的客戶端請(qǐng)求/服務(wù)器響應(yīng)機(jī)制
現(xiàn)在我們介紹了AJAX,對(duì) XMLHttpRequest 對(duì)象以及如何創(chuàng)建它也有了基本的了解。如果閱讀得很仔細(xì),您可能已經(jīng)知道與服務(wù)器上的 Web 應(yīng)用程序打交道的是 JavaScript 技術(shù),而不是直接提交給那個(gè)應(yīng)用程序的 HTML 表單。

還缺少什么呢?到底如何使用 XMLHttpRequest。因?yàn)檫@段代碼非常重要,您編寫(xiě)的每個(gè)AJAX應(yīng)用程序都要以某種形式使用它,先看看 AJAX的基本請(qǐng)求/響應(yīng)模型是什么樣吧。

發(fā)出請(qǐng)求

您已經(jīng)有了一個(gè)嶄新的 XMLHttpRequest 對(duì)象,現(xiàn)在讓它干點(diǎn)活兒吧。首先需要一個(gè) Web 頁(yè)面能夠調(diào)用的 JavaScript 方法(比如當(dāng)用戶輸入文本或者從菜單中選擇一項(xiàng)時(shí))。接下來(lái)就是在所有 Ajax 應(yīng)用程序中基本都雷同的流程:

從 Web 表單中獲取需要的數(shù)據(jù)。
建立要連接的 URL。
打開(kāi)到服務(wù)器的連接。
設(shè)置服務(wù)器在完成后要運(yùn)行的函數(shù)。
發(fā)送請(qǐng)求。
清單 5 中的示例 Ajax 方法就是按照這個(gè)順序組織的:

清單 5. 發(fā)出 Ajax 請(qǐng)求
復(fù)制代碼 代碼如下:

function callServer() {
// Get the city and state from the web form
var city = document.getElementById("city").value;
var state = document.getElementById("state").value;
// Only go on if there are values for both fields
if ((city == null) || (city == "")) return;
if ((state == null) || (state == "")) return;
// Build the URL to connect to
var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);
// Open a connection to the server
xmlHttp.open("GET", url, true);
// Setup a function for the server to run when it's done
xmlHttp.onreadystatechange = updatePage;
// Send the request
xmlHttp.send(null);
}

其中大部分代碼意義都很明確。開(kāi)始的代碼使用基本 JavaScript 代碼獲取幾個(gè)表單字段的值。然后設(shè)置一個(gè) PHP 腳本作為鏈接的目標(biāo)。要注意腳本 URL 的指定方式,city 和 state(來(lái)自表單)使用簡(jiǎn)單的 GET 參數(shù)附加在 URL 之后。

然后打開(kāi)一個(gè)連接,這是您第一次看到使用 XMLHttpRequest。其中指定了連接方法(GET)和要連接的 URL。最后一個(gè)參數(shù)如果設(shè)為 true,那么將請(qǐng)求一個(gè)異步連接(這就是 Ajax 的由來(lái))。如果使用 false,那么代碼發(fā)出請(qǐng)求后將等待服務(wù)器返回的響應(yīng)。如果設(shè)為 true,當(dāng)服務(wù)器在后臺(tái)處理請(qǐng)求的時(shí)候用戶仍然可以使用表單(甚至調(diào)用其他 JavaScript 方法)。

xmlHttp(要記住,這是 XMLHttpRequest 對(duì)象實(shí)例)的 onreadystatechange 屬性可以告訴服務(wù)器在運(yùn)行完成后(可能要用五分鐘或者五個(gè)小時(shí))做什么。因?yàn)榇a沒(méi)有等待服務(wù)器,必須讓服務(wù)器知道怎么做以便您能作出響應(yīng)。在這個(gè)示例中,如果服務(wù)器處理完了請(qǐng)求,一個(gè)特殊的名為updatePage()的方法將被觸發(fā)。

最后,使用值 null 調(diào)用 send()。因?yàn)橐呀?jīng)在請(qǐng)求 URL 中添加了要發(fā)送給服務(wù)器的數(shù)據(jù)(city 和 state),所以請(qǐng)求中不需要發(fā)送任何數(shù)據(jù)。這樣就發(fā)出了請(qǐng)求,服務(wù)器按照您的要求工作。

如果沒(méi)有發(fā)現(xiàn)任何新鮮的東西,您應(yīng)該體會(huì)到這是多么簡(jiǎn)單明了!除了牢牢記住AJAX的異步特性外,這些內(nèi)容都相當(dāng)簡(jiǎn)單。應(yīng)該感激AJAX使您能夠?qū)P木帉?xiě)漂亮的應(yīng)用程序和界面,而不用擔(dān)心復(fù)雜的 HTTP 請(qǐng)求/響應(yīng)代碼。

清單 5 中的代碼說(shuō)明了 Ajax 的易用性。數(shù)據(jù)是簡(jiǎn)單的文本,可以作為請(qǐng)求 URL 的一部分。用 GET 而不是更復(fù)雜的 POST 發(fā)送請(qǐng)求。沒(méi)有 XML 和要添加的內(nèi)容頭部,請(qǐng)求體中沒(méi)有要發(fā)送的數(shù)據(jù);換句話說(shuō),這就是 Ajax 的烏托邦。

不用擔(dān)心,隨著本系列文章的展開(kāi),事情會(huì)變得越來(lái)越復(fù)雜。您將看到如何發(fā)送 POST 請(qǐng)求、如何設(shè)置請(qǐng)求頭部和內(nèi)容類型、如何在消息中編碼 XML、如何增加請(qǐng)求的安全性,可以做的工作還有很多!暫時(shí)先不用管那些難點(diǎn),掌握好基本的東西就行了,很快我們就會(huì)建立一整套的 Ajax 工具庫(kù)。

處理響應(yīng)

現(xiàn)在要面對(duì)服務(wù)器的響應(yīng)了?,F(xiàn)在只要知道兩點(diǎn):

什么也不要做,直到 xmlHttp.readyState 屬性的值等于4。
服務(wù)器將把響應(yīng)填充到 xmlHttp.responseText 屬性中。
其中的第一點(diǎn),即就緒狀態(tài),將在下一篇文章中詳細(xì)討論,您將進(jìn)一步了解 HTTP 請(qǐng)求的階段,可能比您設(shè)想的還多?,F(xiàn)在只要檢查一個(gè)特定的值(4)就可以了(下一期文章中還有更多的值要介紹)。第二點(diǎn),使用 xmlHttp.responseText 屬性獲得服務(wù)器的響應(yīng),這很簡(jiǎn)單。清單 6 中的示例方法可供服務(wù)器根據(jù) 清單 5 中發(fā)送的數(shù)據(jù)調(diào)用。

清單 6. 處理服務(wù)器響應(yīng)
復(fù)制代碼 代碼如下:

function updatePage() {
if (xmlHttp.readyState == 4) {
var response = xmlHttp.responseText;
document.getElementById("zipCode").value = response;
}
}

這些代碼同樣既不難也不復(fù)雜。它等待服務(wù)器調(diào)用,如果是就緒狀態(tài),則使用服務(wù)器返回的值(這里是用戶輸入的城市和州的 ZIP 編碼)設(shè)置另一個(gè)表單字段的值。于是包含 ZIP 編碼的 zipCode 字段突然出現(xiàn)了,而用戶沒(méi)有按任何按鈕!這就是前面所說(shuō)的桌面應(yīng)用程序的感覺(jué)。快速響應(yīng)、動(dòng)態(tài)感受等等,這些都只因?yàn)橛辛诵⌒〉囊欢?Ajax 代碼。

細(xì)心的讀者可能注意到 zipCode 是一個(gè)普通的文本字段。一旦服務(wù)器返回 ZIP 編碼,updatePage() 方法就用城市/州的 ZIP 編碼設(shè)置那個(gè)字段的值,用戶就可以改寫(xiě)該值。這樣做有兩個(gè)原因:保持例子簡(jiǎn)單,說(shuō)明有時(shí)候可能希望 用戶能夠修改服務(wù)器返回的數(shù)據(jù)。要記住這兩點(diǎn),它們對(duì)于好的用戶界面設(shè)計(jì)來(lái)說(shuō)很重要。


3.3 [題外]如何連接Web表單
還有什么呢?實(shí)際上沒(méi)有多少了。一個(gè) JavaScript 方法捕捉用戶輸入表單的信息并將其發(fā)送到服務(wù)器,另一個(gè) JavaScript 方法監(jiān)聽(tīng)和處理響應(yīng),并在響應(yīng)返回時(shí)設(shè)置字段的值。所有這些實(shí)際上都依賴于調(diào)用 第一個(gè) JavaScript 方法,它啟動(dòng)了整個(gè)過(guò)程。最明顯的辦法是在 HTML 表單中增加一個(gè)按鈕,但這是 2001 年的辦法,您不這樣認(rèn)為嗎?還是像 清單 7 這樣利用 JavaScript 技術(shù)吧。

清單 7. 啟動(dòng)一個(gè) Ajax 過(guò)程
復(fù)制代碼 代碼如下:

<form>
<p>City: <input type="text" name="city" id="city" size="25"
onChange="callServer();" />
<p>State: <input type="text" name="state" id="state" size="25"
onChange="callServer();" />
<p>Zip Code: <input type="text" name="zipCode" id="city" size="5" />
</form>

如果感覺(jué)這像是一段相當(dāng)普通的代碼,那就對(duì)了,正是如此!當(dāng)用戶在 city 或 state 字段中輸入新的值時(shí),callServer() 方法就被觸發(fā),于是 Ajax 開(kāi)始運(yùn)行了。有點(diǎn)兒明白怎么回事了吧?好,就是如此!

4. 開(kāi)發(fā)AJAX應(yīng)用面臨的問(wèn)題是什么?如何解決的?
對(duì)程序員而言,開(kāi)發(fā)Ajax應(yīng)用最頭痛的問(wèn)題莫過(guò)于以下幾點(diǎn):

Ajax在本質(zhì)上是一個(gè)瀏覽器端的技術(shù),首先面臨無(wú)可避免的第一個(gè)問(wèn)題即是瀏覽器的兼容性問(wèn)題。各家瀏覽器對(duì)于JavaScript/DOM/CSS的支持總有部分不太相同或是有Bug,甚至同一瀏覽器的各個(gè)版本間對(duì)于JavaScript/DOM/CSS的支持也有可能部分不一樣。這導(dǎo)致程序員在寫(xiě)Ajax應(yīng)用時(shí)花大部分的時(shí)間在調(diào)試瀏覽器的兼容性而非在應(yīng)用程序本身。
Ajax技術(shù)之主要目的在于局部交換客戶端及服務(wù)器之間的數(shù)據(jù)。如同傳統(tǒng)之主從架構(gòu),無(wú)可避免的會(huì)有部分的業(yè)務(wù)邏輯會(huì)實(shí)現(xiàn)在客戶端,或部分在客戶端部分在服務(wù)器。由于業(yè)務(wù)邏輯可能分散在客戶端及服務(wù)器,且以不同之程序語(yǔ)言實(shí)現(xiàn),這導(dǎo)致Ajax應(yīng)用程序極難維護(hù)。如有用戶接口或業(yè)務(wù)邏輯之更動(dòng)需求,再加上前一個(gè)JavaScript/DOM/CSS之兼容性問(wèn)題,Ajax應(yīng)用往往變成程序員的夢(mèng)魘。針對(duì)業(yè)務(wù)邏輯分散的問(wèn)題,Ajax開(kāi)發(fā)框架大致可分為兩類:
將業(yè)務(wù)邏輯及表現(xiàn)層放在瀏覽器,數(shù)據(jù)層放在服務(wù)器:因?yàn)樗械某绦蛞訨avaScript執(zhí)行在客戶端,只有需要數(shù)據(jù)時(shí)才向服務(wù)器要求服務(wù),此法又稱為胖客戶端(fat client)架構(gòu)。服務(wù)器在此架構(gòu)下通常僅用于提供及儲(chǔ)存數(shù)據(jù)。此法的好處在于程序員可以充分利用JavaScript搭配業(yè)務(wù)邏輯來(lái)做出特殊的用戶接口,以符合終端用戶的要求。但是問(wèn)題也不少,主因在第一,JavaScript語(yǔ)言本身之能力可能不足以處理復(fù)雜的業(yè)務(wù)邏輯。第二,JavaScript的執(zhí)行效能一向不好。第三,JavaScript訪問(wèn)服務(wù)器數(shù)據(jù),仍需適當(dāng)?shù)姆?wù)器端程序之配合。第四,瀏覽器兼容性的問(wèn)題又出現(xiàn)。有些Ajax開(kāi)發(fā)框架如DWR企圖以自動(dòng)生成JavaScript之方式來(lái)避免兼容的問(wèn)題,并開(kāi)立通道使得JavaScript可以直接調(diào)用服務(wù)器端的Java程序來(lái)簡(jiǎn)化數(shù)據(jù)的訪問(wèn)。但是前述第一及第二兩個(gè)問(wèn)題仍然存在,程序員必須費(fèi)相當(dāng)?shù)牧獠拍苓_(dá)到應(yīng)用程序之規(guī)格要求,或可能根本無(wú)法達(dá)到要求。
將表現(xiàn)層、業(yè)務(wù)邏輯、及數(shù)據(jù)層放在服務(wù)器,瀏覽器僅有用戶接口引擎(User Interface engine);此法又稱為瘦客戶端(thin client)架構(gòu),或中心服務(wù)器(server-centric)架構(gòu)。瀏覽器的用戶接口引擎僅用于反映服務(wù)器的表現(xiàn)層以及傳達(dá)用戶的輸入回到服務(wù)器的表現(xiàn)層。由瀏覽器所觸發(fā)之事件亦送回服務(wù)器處理,根據(jù)業(yè)務(wù)邏輯來(lái)更新表現(xiàn)層,然后反映回瀏覽器。因?yàn)樗袘?yīng)用程序完全在服務(wù)器執(zhí)行,數(shù)據(jù)及表現(xiàn)層皆可直接訪問(wèn),程序員只需使用服務(wù)器端相對(duì)較成熟之程序語(yǔ)言(如Java語(yǔ)言)即可,不需再學(xué)習(xí)JavaScript/DOM/CSS,在開(kāi)發(fā)應(yīng)用程序時(shí)相對(duì)容易。缺點(diǎn)在于用戶接口引擎以及表現(xiàn)層通常以標(biāo)準(zhǔn)組件的形式存在,如需要特殊組件(用戶接口)時(shí),往往須待原框架之開(kāi)發(fā)者提供,緩不濟(jì)急。如開(kāi)源碼Ajax開(kāi)發(fā)框架ZK目前支持XUL及XHTML組件,尚無(wú)XAML之支持。
Ajax是以異步的方式向服務(wù)器提交需求。對(duì)服務(wù)器而言,其與傳統(tǒng)的提交窗體需求并無(wú)不同,而且由于是以異步之方式提交,如果同時(shí)有多個(gè)Ajax需求及窗體提交需求,將無(wú)法保證哪一個(gè)需求先獲得服務(wù)器的響應(yīng)。這會(huì)造成應(yīng)用程序典型的多進(jìn)程(process)或多線程(thread)的競(jìng)爭(zhēng)(racing)問(wèn)題。程序員因此必須自行處理或在JavaScript里面動(dòng)手腳以避免這類競(jìng)爭(zhēng)問(wèn)題的發(fā)生(如Ajax需求未響應(yīng)之前,先disable送出按鈕),這又不必要的增加了程序員的負(fù)擔(dān)。目前已知有自動(dòng)處理此問(wèn)題之開(kāi)發(fā)框架似乎只有ZK。

相關(guān)文章

最新評(píng)論