AJAX簡介 AJAX是Asynchronous JavaScript and XML的簡稱。AJAX其實並非一種新的技術,而是網路瀏覽器裡已有的三項重要特徵的結合: 1. 瀏覽器可通過JavaScript和Web Server通訊。 2. JavaScript能在不重新整理頁面的情況下動態地改變頁面的值。 3. 瀏覽器能解析XML檔案。 作為AJAX的組成部分,這三項特徵已經存在很久了,直至Google推出Google Map、GMail和Google Suggest後,AJAX才風行起來,以致於很多人誤認為AJAX是Google發明的新技術。 傳統的網路頁面工作流程是瀏覽器向Web Server發送請求(Request),在收到資料後重新整理整個頁面以顯示新的資料,如所示: 在伺服器端進行操作的時候,使用者能做的就是等待,以致於使用者做網上操作的體驗不比使用用戶端程式來得連貫。 運用AJAX,可在使用者進行操作的同時通過事件觸發JavaScript,在後台串連到伺服器得到資料,然後在不重新整理整個頁面的情況下動態地改變頁面的數值,其過程如所示: 使用者在使用者頁面上做操作,比如在輸入筐內輸入、點擊按鈕……這些都會產生事件,並觸發JavaScript。JavaScript執行時可通過 XMLHttpRequest向伺服器發送Http Request,並從伺服器得到Http Response,根據Http Response的內容在不重新整理頁面的情況下動態地改變頁面的內容。XMLHttpRequest是瀏覽器裡已定義的對象,它是AJAX技術的核心組成部分,JavaScript通過它和伺服器通訊,並通過它來解析從伺服器傳回來的XML檔案。XMLHttpRequest最早由微軟作為一個 ActiveX對象實現,之後其它流行的瀏覽器步其後塵都實現了XMLHttpRequest。在定義XMLHttpRequest對象時,IE和別的瀏覽器略有不同,這在後面的例子中會有說明。 學習使用AJAX 本文將用一個例子來進一步說明AJAX。在這個例子中,伺服器端有一個Servlet會產生一個0~100的整數。在使用者端的使用者會被要求在輸入筐中輸入一個0~100的數,如果這個數和伺服器端自動產生的數一致,頁面則會出現“恭喜,您猜對了!”的字樣。在使用者輸入的同時,在輸入筐的右端有提示告訴使用者,輸入的數是大了還是小了。這些提示都是在不重新整理頁面的情況下,動態完成的。如示: 接下來,我們就邊編程式邊學習AJAX。 準備工作一:建立伺服器端的Servlet 在例子中,這個Servlet叫“ValidateGuess”,它的URL pattern是/ValidateGuess,這個Servlet可以做以下幾件事: 1.隨機產生一個0~100之間的整數。 2.在收到Http Request的時候,從Http Request中拿到傳入的數,將它和上一步產生的整數比較,並通過Http Response傳回比較結果,結果的形式是一段XML文本,比如: …… <message> tooSmall </message> …… 準備工作二:建立使用者頁面Ajax.jsp 頁面很簡單,: 要注意的有兩點: 1. 輸入筐的定義是<input type="text" id="guess" name="id" onkeyup="validate()">,onkeyup定義了validate()函數為keyup事件的listener,當使用者在輸入筐內輸入時,validate()函數就會被調用。validate()函數的程式如下: function validate() { var aNumber = document.getElementById("guess"); var url = "http://localhost:8080/AJAX/ValidateGuess?guess=" + escape(aNumber.value); initRequest(); sendRequest(url); } initRequest()和sendRequest()函數在下文會做進一步解釋。 2. 在輸入筐右側有一個<div id="messageText"><div>,這在JSP初始時是看不到的,它的內容會隨使用者的輸入動態地出現並改變。 準備工作做好了,現在我們就可以在Ajax.jsp中加入JavaScript來實現AJAX了。 第一步:建立XMLHttpRequest對象 前面已提到XMLHttpRequest是瀏覽器裡已定義的對象,它先由微軟在IE5裡實現,後來其它主流的瀏覽器也加入了對它的支援,所以在定義這個對象時IE和別的瀏覽器略有不同,如以下的程式所示(在文中只包括了主要的程式片斷): …… var req; function initRequest() { if (window.XMLHttpRequest) { //IE之外的瀏覽器 req = new XMLHttpRequest(); } else if (window.ActiveXObject) {//IE 5.0 and up req = new ActiveXObject("Microsoft.XMLHTTP"); } } …… 至此,在Javascript裡就得到了一個XMLHttpRequest對象,以下的程式就可以對這個名為“req”的XMLHttpRequest的對象進行操作了。 第二步:用XMLHttpRequest來向伺服器發Request function sendRequest(url){ req.open("GET", url, true); req.onreadystatechange = handleResponse; req.send(null); } 在這一步驟中調用了幾個重要的XMLHttpRequest函數和參數:
- open(”method”, “URL”[, asyncFlag[, username[,password]]])
open是XMLHttpRequest的函數,此函數有五個參數,後三個為選擇性參數。 method——Http需求方式,支援“Post”和“Get”。 URL——伺服器端程式的URL。 asyncFlag——定義Request是否是並發;如果asyncFlag=true,send()函數在發送Request後馬上返回;如果 asyncFlag=false,send()函數必須在收到回執後才返回。預設值是true。 username——使用者名稱,有些URL要求request帶有使用者名稱;一般不會用到。 password——密碼;一般不會用到。
readyState是XMLHttpRequest對象的參數,用於表示此對象的狀態,可能的狀態有五個: 0 UNINITIALIZED——表示open()函數還未調用。 1 LOADING——表示send()函數還未調用。 2 LOADED——表示send()函數已調用。 3 INTERACTIVE——表示send()函數調用後,但需求還未被滿足時的狀態。 4 COMPLETED——需求被滿足。 XMLHttpRequest對象被建立之後,它的狀態就在這五個值之間轉換,每次狀態轉變都會觸發一個readyStateChange的事件,可定義listener來對事件進行處理。
- onreadystatechange=handleResponse
onreadystatechange是XMLHttpRequest對象的參數,用來定義此對象狀態改變事件發生時的listenser,它的值對應一個JavaScript函數——在這個例子中我們的listenser叫“handleResponse”。注意,handleResponse是一個你自己定義的函數,但要保證onreadysatechange的值和你自己定義的函數名一致。 XMLHttpRequest還有其它參數和函數,想要進一步瞭解的讀者可在http://www.xulplanet.com/references /objref/XMLHttpRequest.html找到關於XMLHttpRequest的詳細文本和資訊。 第三步:處理readyStateChange事件 前面提到XMLHttpRequest的onreadystatechange的參數被定為handleResponse,每當 XMLHttpRequest的狀態改變時,這個函數都會被調用,但我們只對readyState=4(COMPLETED)感興趣。 handleResponse的程式如下: function handleResponse() { if (req.readyState == 4) { if (req.status == 200) { processMessage(); } } }
status是XMLHttpRequest的參數,代表Http request的狀態,比如說404是沒有找到伺服器,500是伺服器端程式出錯,200代表一切OK。當XMLHttpRequest的readyState是4,並且Http Request的狀態是200時,就可調用processMessage()函數來對伺服器返回的結果進行處理了,processMessage()的程式如下: function processMessage() { var messageElement = req.responseXML.getElementsByTagName("message")[0]; var message = messageElement.childNodes[0].nodeValue; var mdiv = document.getElementById("messageText"); if (message == "tooBig") { mdiv.innerHTML = "<div style="color:red">太大</ div>"; } else if(message == "tooSmall"){ mdiv.innerHTML = "<div style="color:red">太小</ div>"; } else if(message == "invalid"){ mdiv.innerHTML = "<div style="color:red">不是數字</ div>"; } else if(message =="outOfRange") { mdiv.innerHTML = "<div style="color:red">超出範圍</ div>"; } else { mdiv.innerHTML = "<div style="color:green">恭喜,您猜對了!</ div>"; } } processMessage函數做了兩件事: 1. 解析了伺服器的傳回值 XMLHttpRequest自動地把從伺服器端返回的Http Response中的XML,轉換成了樹狀的DOM Document結構並存在responseXML參數裡,通過它可解析返回的XML檔案並最終獲得傳回值。讀者可到http: //www.xulplanet.com/references/objref/Document.html找到詳細的關於DOM Document的文本。 2. 動態地更新頁面 前面提到在頁面的輸入筐右側有一個<div id=”messageText”>,processMessage()通過mdiv.innerHTML動態地改變它的內容。 至此,一個完整的AJAX程式就開發完畢,只要把完整的來源程式進行編譯並部署到伺服器上就可以運行了。AJAX能開發出像Google Map那樣完美的應用,但它的基本原理其實是很簡單的,熟悉JavaScript的讀者在原來的基礎上只需要再學習使用XMLHttpRequest就行了。但要把AJAX的潛力發揮得淋漓盡致,開發出像Google Map那樣熟練的應用程式還得下很大的功夫。 AJAX的注意事項 AJAX作為一種新一代的網路頁面開發架構,使我們開發具有豐富人機互動功能的頁面成為可能。但AJAX也有它的不足之處,在您決定使用AJAX之前,一定要確定下列AJAX的不足不會對您的應用程式的開發造成影響: 1. 只有比較新的網路瀏覽器支援AJAX,如果您的程式運用需要支援比較老的網路瀏覽器,或者是基於行動裝置的瀏覽器,AJAX將不是個好的選擇。以下是支援AJAX的瀏覽器:
- Microsoft IE 5.0以上
- Apple Safari 1.2以上
- Firefox 1.0以上
- Netscape 7.1以上
- Opera 7.6以上
2. 因為AJAX的運作是在不重新整理頁面的情況下進行的,瀏覽器中的地址欄將不再反映當前頁面的狀態,所以,書籤功能將不能保證使用者在下一次訪問時,可得到相同的內容,同時AJAX也會打亂瀏覽器裡的“Back”鍵。 3. 如果使用不當,AJAX會不必要地增大網路資料的流量,從而降低整個系統的效能。 4. AJAX中的JavaScript在用戶端執行,和伺服器端的代碼不同,AJAX的代碼會被下載到用戶端,要注意不要在AJAX的代碼中放入敏感資訊,以免造成泄密。 |