利用AJAX技術開發應用程式實戰
AJAX,一個非同步JavaScript和XML的縮減詞,是當今快速發展的Web開發界十分熱門的技術。在這項新技術提供巨大能力的同時,它也燃發了在"Back"按鈕問題上的不容置疑的爭論。本文作者將向你解釋怎樣在真實世界中使用AJAX以及怎樣在一個工程中評估它的價值。在你讀完本文後,你就會明白什麼是AJAX,在什麼情況下,為什麼以及怎樣使用這項技術。
一、 簡介
AJAX,一個非同步JavaScript和XML的縮減詞,是最近出來的技術詞語。非同步意味著你可以經由超文字傳輸通訊協定 (HTTP)(HTTP)向一個伺服器發出請求並且在等待該響應時繼續處理另外的資料。這就意味著,例如,你可以調用一個伺服器端指令碼來從一個資料庫中以XML方式檢索資料,把資料發送到儲存在一個資料庫的伺服器指令碼,或者簡單地裝載一個XML檔案以填充你的Web網站而不需重新整理該頁面。然而,在這項新技術提供巨大能力的同時,它也引起了在"Back"按鈕問題上的很多爭論。本文將協助你確定在真實世界中何時使用AJAX是最佳選擇。
首先,我假定你對縮減詞JavaScript和XML部分有一個基本瞭解。儘管你能通過AJAX請求任何類型的文字檔,但是我在此主要集中討論XML。我將解釋怎樣在真實世界中使用AJAX以及怎樣在一個工程中評估它的價值。在你讀完本文後,你將會明白什麼是AJAX,在什麼情況下,為什麼以及怎樣使用這項技術。你將要學習,在保持給使用者提供直觀體驗的同時怎樣建立對象,發出請求以及定製響應。
我已建立了一個適合於本文的樣本工程(你可以下載原始碼)。這個樣本實現了一個簡單的請求-它裝載一個包含頁面內容的XML檔案並且分析資料以把它顯示在一個HTML頁面中。
二、 常規屬性和方法
表1和2提供了一個屬性和方法的概述-它們為Windows Internet Explorer 5,Mozilla,Netscape 7,Safari 1.2,和Opera等瀏覽器所支援。
表1屬性
屬性 |
描述 |
onreadystatechange |
當請求對象變化時該事件處理器啟用。 |
readyState |
返回指示對象的目前狀態的值。 |
responseText |
來自伺服器的響應串的版本。 |
responseXML |
來自伺服器的響應的DOM相容的文檔對象。 |
status |
來自伺服器的響應的狀態代碼。 |
statusText |
以一個字串形式返回的狀態訊息。 |
表2方法
方法 |
描述 |
Abort() |
取消當前HTTP請求。 |
getAllResponseHeaders() |
檢索所有的HTTP頭值。 |
getResponseHeader("headerLabel") |
從響應體中檢索一個HTTP頭部的值。 |
open("method","URL"[,asyncFlag[,"userName"[,"password"]]]) |
初始化一個MSXML2.XMLHTTP請求,並從該請求指定方法,URL和認證資訊。 |
send(content) |
發送一個HTTP請求到伺服器並接收響應。 |
setRequestHeader("label", "value") |
指定一個HTTP頭的名字。 |
三、 從哪裡開始
首先,你需要建立XML檔案-後面我們對之進行請求並作為頁面內容進行分析。你正在請求的檔案必須與目標工程駐留在相同的伺服器上。
下一步,建立發出請求的HTML檔案。當頁面通過使用頁面主體中的onload方法進行載入時,該請求發生。接著,該檔案需要一個有ID的div標籤,這樣當我們準備好要顯示內容時就可以對之進行定位。當你做完所有這些,你的頁面的主體看上去如下:
<body onload="makeRequest('xml/content.xml');">
<div id="copy"></div>
</body>
四、 建立請求對象
為了建立請求對象,你必須檢查是否瀏覽器使用XMLHttpRequest或ActiveXObject。這兩個對象之間的主要區別在於使用它們的瀏覽器。Windows IE 5 及以上版本使用ActiveX對象;而Mozilla,Netscape 7,Opera和Safari 1.2及以上版本使用XMLHttpRequest對象。另外一個區別是你建立對象的方式:Opera,Mozilla,Netscape和Safari允許你簡單地調用該對象的構造器,但是Windows IE需要把對象的名字傳遞到ActiveX構造器中。下面是怎樣建立代碼來決定要使用哪個對象和怎樣建立它的樣本:
if(window.XMLHttpRequest)
{ request = new XMLHttpRequest();}
else if(window.ActiveXObject)
{ request = new ActiveXObject("MSXML2.XMLHTTP");}
五、 發出請求
現在既然你已經建立了你的請求對象,那麼你已經為向伺服器發出請求作了準備。建立一個到事件處理器的參考以聽取onreadystatechange事件。然後,該事件處理器方法將在狀態發生變化時作出響應。一旦我們完成請求,我們就開始建立這個方法。開啟串連以GET或POST一個定製的URL-在此是一個content.xml,並且設定一個布爾定義-是否你想要進行非同步呼叫。
現在到了發出請求的時間了。在這個樣本中,我使用了null,因為我們使用的是GET;為了使用POST,你需要使用下面這個方法發出一個查詢串:
request.onreadystatechange = onResponse;
request.open("GET". url, true);
request.send(null);
六、 定製載入和錯誤處理訊息
你為onreadystatechange方法建立的事件處理器正是集中進行載入和處理錯誤的場所。現在到了考慮使用者並針對他們與之互動的內容的狀態提供反饋的時候了。在這個執行個體中,我針對所有的裝載狀態碼提供反饋,並且也對最經常發生的錯誤處理狀態碼提供一些基本的反饋。為了顯示請求對象的目前狀態,readyState屬性包括顯示在下表中的一些值。
值 |
描述 |
0 |
未初始化,對象沒有用資料進行初始化。 |
1 |
裝載中,對象正在裝載它的資料。 |
2 |
裝載結束,對象完成了它的資料的裝載。 |
3 |
可互動,使用者能與對象互動了,儘管它還沒有裝載結束。 |
4 |
完成,對象已經完全被初始化。 |
W3C中有很長的一串有關HTTP狀態碼的定義。我選擇了兩個狀態碼:
·200:請求成功了。
·404:伺服器沒有找到與所請求的檔案相匹配的任何東西。
最後,我檢查任何另外的狀況代碼-它們將產生一個錯誤並提供一個一般錯誤資訊。下面是一個程式碼範例-你可以用之來處理這些情況。注意,我在定位我們前面在HTML檔案的主體中建立的div ID並且對它應用裝載和/或錯誤資訊-通過innerHTML方法-這個方法用於設定在div對象的開始和結束標籤之間的HTML:
if(obj.readyState == 0)
{ document.getElementById('copy').innerHTML = "Sending Request...";}
if(obj.readyState == 1)
{ document.getElementById('copy').innerHTML = "Loading Response...";}
if(obj.readyState == 2)
{ document.getElementById('copy').innerHTML = "Response Loaded...";}
if(obj.readyState == 3)
{ document.getElementById('copy').innerHTML = "Response Ready...";}
if(obj.readyState == 4){
if(obj.status == 200){ return true; }
else if(obj.status == 404)
{
// 添加一個定製訊息或把使用者重新導向到另外一個頁面
document.getElementById('copy').innerHTML = "File not found";
}
else
{document.getElementById('copy').innerHTML = "There was a problem retrieving the XML."; }
}
當狀況代碼為200時,這意味著請求成功。下面開始進行響應了。
七、 分析響應
當你準備好分析來自請求對象的響應時,真正的工作開始了。現在你可以用你請求的資料開始工作。僅為測試目的,在開發期間,可以使用responseText和responseXML屬性來顯示來自響應的未經處理資料。為了存取XML響應中的結點,首先使用你建立的請求對象,定位到responseXML屬性以檢索(你可能已經猜測出來)來自響應的XML。定位到documentElement-它檢索一個到XML響應的根結點的參考。
var response = request.responseXML.documentElement;
現在既然你有了到響應的根結點的參考,那麼你可以使用getElementsByTagName()以結點名字來檢索childNodes。下面一行用一個頭部的nodeName來定位一個childNode:
response.getElementsByTagName('header')[0].firstChild.data;
使用firstChild.data可以允許你存取該元素中的文本:
response.getElementsByTagName('header')[0].firstChild.data;
下面是怎樣建立這些代碼的完整的例子:
var response = request.responseXML.documentElement;
var header = response.getElementsByTagName('header')[0].firstChild.data;
document.getElementById('copy').innerHTML = header;
八、 需求分析
現在既然你知道怎樣使用AJAX的基礎知識,那麼下一步就是決定是否在一工程使用它。須記住的最重要的事情是,在你還沒有重新整理頁面時你無法使用"Back"按鈕。為此,可以先專註於你的工程中的一小部分-它能夠從使用這種類型的互動中受益。例如,你可以建立一個表單-它在使用者每次輸入一個輸入欄位或一個字母時查詢一個指令碼以便進行即時校正。你可以建立一個拖放頁面-在釋放一項時,它能夠把資料發送到一個指令碼中並把該頁面的狀態儲存到一個資料庫中。使用AJAX的理由毫無疑問是存在的;並且這種使用無論對開發人員還是使用者都會帶來益處;這全依賴於具體的條件和執行情況。
還有其它方法可用來解決"Back"按鈕的問題,例如使用Google Gmail-它現在能夠為你的操作提供一種撤消功能而不重新整理該頁面。以後還會出現許多更具創造性的例子-它們將通過提供給開發人員建立獨特即時的體驗的手段給使用者帶來更大的好處。
九、 結論
儘管AJAX允許我們構建新的和改進的方式來與一個WEB頁面進行互動;但是作為開發人員,我們需要牢記產品是不考慮技術的;它關心的是使用者以及其如何與使用者進行互動。沒有了使用者群,我們構建的工程毫無用處。基於這個標準,我們就能評估應該使用什麼技術以及何時使用它們來建立對相應使用者有用的應用軟體。