4、 發送請求 在AJAX中,許多使用XMLHttpRequest的請求都是從一個HTML事件(例如一個調用JavaScript函數的按鈕點擊 (onclick)或一個按鍵(onkeypress))中被初始化的。AJAX支持包括表單校驗在內的各類應用程序。有時,在填充表單的其它內容以前要 求校驗一個惟一的表單域。例如要求使用一個惟一的UserID來註冊表單。若是不是使用AJAX技術來校驗這個UserID域,那麼整個表單都必須被填充 和提交。若是該UserID不是有效的,這個表單必須被從新提交。例如,一個相應於一個要求必須在服務器端進行校驗的Catalog ID的表單域可能按下列形式指定:
<form name="validationForm" action="validateForm" method="post"> <table> <tr><td>Catalog Id:</td> <td> <input type="text" size="20" id="catalogId" name="catalogId" autocomplete="off" onkeyup="sendRequest()"> </td> <td><div id="validationMessage"></div></td> </tr> </table></form> |
前面的HTML使用validationMessage div來顯示相應於這個輸入域Catalog Id的一個校驗消息。onkeyup事件調用一個JavaScript sendRequest()函數。這個sendRequest()函數建立一個XMLHttpRequest對象。建立一個XMLHttpRequest 對象的過程因瀏覽器實現的不一樣而有所區別。若是瀏覽器支持XMLHttpRequest對象做爲一個窗口屬性(全部普通的瀏覽器都是這樣的,除了IE 5和IE 6以外),那麼,代碼能夠調用XMLHttpRequest的構造器。若是瀏覽器把XMLHttpRequest對象實現爲一個 ActiveXObject對象(就象在IE 5和IE 6中同樣),那麼,代碼可使用ActiveXObject的構造器。下面的函數將調用一個init()函數,它負責檢查並決定要使用的適當的建立方法- 在建立和返回對象以前。
<script type="text/javascript"> function sendRequest(){ var xmlHttpReq=init(); function init(){ if (window.XMLHttpRequest) { return new XMLHttpRequest(); } else if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP"); } } </script> |
接下來,你須要使用Open()方法初始化XMLHttpRequest對象-指定HTTP方法和要使用的服務器URL。
var catalogId=encodeURIComponent(document.getElementById("catalogId").value); xmlHttpReq.open("GET", "validateForm?catalogId=" + catalogId, true); |
默認狀況下,使用XMLHttpRequest發送的HTTP請求是異步進行的,可是你能夠顯式地把async參數設置爲true,如上面所展現的。 在 這種狀況下,對URL validateForm的調用將激活服務器端的一個servlet,可是你應該可以注意到服務器端技術不是根本性的;實際上,該URL多是一個 ASP,ASP.NET或PHP頁面或一個Web服務-這可有可無,只要該頁面可以返回一個響應-指示CatalogID值是不是有效的-便可。由於你在 做一個異步調用,因此你須要註冊一個XMLHttpRequest對象將調用的回調事件處理器-當它的readyState值改變時調用。記 住,readyState值的改變將會激發一個readystatechange事件。你可使用onreadystatechange屬性來註冊該回調 事件處理器。
xmlHttpReq.onreadystatechange=proce***equest; |
而後,咱們須要使用send()方法發送該請求。由於這個請求使用的是HTTP GET方法,因此,你能夠在不指定參數或使用null參數的狀況下調用send()方法。
5、 處理請求 在這個示例中,由於HTTP方法是GET,因此在服務器端的接收servlet將調用一個doGet()方法,該方法將檢索在URL中指定的catalogId參數值,而且從一個數據庫中檢查它的有效性。 本文示例中的這個servlet須要構造一個發送到客戶端的響應;並且,這個示例返回的是XML類型,所以,它把響應的HTTP內容類型設置爲 text/xml而且把Cache-Control頭部設置爲no-cache。設置Cache-Control頭部能夠阻止瀏覽器簡單地從緩存中重載頁 面。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ... ... response.setContentType("text/xml"); response.setHeader("Cache-Control", "no-cache"); } |
來自於服務器端的響應是一個XML DOM對象,此對象將建立一個XML字符串-其中包含要在客戶端進行處理的指令。另外,該XML字符串必須有一個根元素。
out.println("<catalogId>valid</catalogId>"); |
【注意】XMLHttpRequest對象的設計目的是爲了處理由普通文本或XML組成的響應;可是,一個響應也多是另一種類型,若是用戶代理(UA)支持這種內容類型的話。 當請求狀態改變時,XMLHttpRequest對象調用使用onreadystatechange註冊的事件處理器。所以,在處理該響應以前,你的事 件處理器應該首先檢查readyState的值和HTTP狀態。當請求完成加載(readyState值爲4)而且響應已經完成(HTTP狀態 爲"OK")時,你就能夠調用一個JavaScript函數來處理該響應內容。下列腳本負責在響應完成時檢查相應的值並調用一個 proce***esponse()方法。
function proce***equest(){ if(xmlHttpReq.readyState==4){ if(xmlHttpReq.status==200){ proce***esponse(); } } } |
該proce***esponse()方法使用XMLHttpRequest對象的responseXML和responseText屬性來檢索 HTTP響應。如上面所解釋的,僅當在響應的媒體類型是text/xml,application/xml或以+xml結尾時,這個 responseXML纔可用。這個responseText屬性將以普通文本形式返回響應。對於一個XML響應,你將按以下方式檢索內容:
var msg=xmlHttpReq.responseXML; |
藉助於存儲在msg變量中的XML,你可使用DOM方法getElementsByTagName()來檢索該元素的值:
var catalogId=msg.getElementsByTagName("catalogId")[0].firstChild.nodeValue; |
最後,經過更新Web頁面的validationMessage div中的HTML內容並藉助於innerHTML屬性,你能夠測試該元素值以建立一個要顯示的消息:
if(catalogId=="valid"){ var validationMessage = document.getElementById("validationMessage"); validationMessage.innerHTML = "Catalog Id is Valid"; } else { var validationMessage = document.getElementById("validationMessage"); validationMessage.innerHTML = "Catalog Id is not Valid"; } |
6、 小結 上面就是XMLHttpRequest對象使用的全部細節實現。經過沒必要把Web頁面寄送到服務器而實現數據傳送,XMLHttpRequest對象爲 客戶端與服務器之間提供了一種動態的交互能力。你可使用JavaScript啓動一個請求並處理相應的返回值,而後使用瀏覽器的DOM方法更新頁面中的 數據。 |