一、簡介
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頁 面進行互動; 但是作為開發人員,我們需要牢記產品是不考慮技術的; 它關心的是使用者以及其如何與使用者 進行互動。沒有了使用者群,我們構建的工程毫無用處。基於這個標準,我們就能評估應該使用什麼技術 以及何時使用它們來建立對相應使用者有用的應用。