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: