Ajax 基礎(chǔ)和例子
Ajax -- Asynchronous JavaScript and XML Ajax 使用的是JavaScript + DOM + CSS + XMLHttpRequest的技術(shù),是目前Web2.0更加流行的技術(shù).
與傳統(tǒng)網(wǎng)絡(luò)應(yīng)用相比,Ajax具備更加直觀和方便的用戶交互. 為什么呢? 比如, 我們需要點(diǎn)擊鏈接或按鈕來(lái)激發(fā)事件,而使用Ajax只要移動(dòng)鼠標(biāo)或者在一個(gè)輸入框輸入字母已經(jīng)可以觸發(fā)事件. 傳統(tǒng)的網(wǎng)絡(luò)應(yīng)用是基于page-driven的模式, 使用的是'click, wait a refresh the whole page' 模式, 而Ajax是通過(guò)data-driven的模式來(lái)提供網(wǎng)絡(luò)頁(yè)面的, 采用的是部分頁(yè)面更新的模式, 頁(yè)面中只更新有新數(shù)據(jù)的部分,其它的部分依然不變,所以依然可以操作.
Ajax就象它的名字一樣, 可以異步地在瀏覽器和服務(wù)器之間進(jìn)行交流, 當(dāng)服務(wù)器端處理submit過(guò)來(lái)的數(shù)據(jù)的同時(shí), 客戶依然可以正常地處理瀏覽器端同一頁(yè)面的其他功能.
那么Ajax和傳統(tǒng)網(wǎng)絡(luò)應(yīng)用相比是怎樣工作的呢?下面這張圖可以讓你了解清楚.

傳統(tǒng)的網(wǎng)絡(luò)應(yīng)用在瀏覽器和服務(wù)器之間的交流是直來(lái)直去的, 而Ajax的網(wǎng)絡(luò)應(yīng)用在瀏覽器中有一個(gè)Ajax引擎,這個(gè)引擎實(shí)際上就是一個(gè)Javascript的對(duì)象XMLHttpRequest, 而XMLHttpRequest負(fù)責(zé)瀏覽器和服務(wù)器的異步交流.
XMLHttpRequest既然是Javascript的對(duì)象, 當(dāng)然需要一些Javascript的代碼來(lái)生成, 它目前支持大部分的瀏覽器,包括了Mozilla, Firefox等等.
服務(wù)器端依然可以使用傳統(tǒng)的技術(shù)如servlet, JSP, JSF,Struts等等,但會(huì)有一些小的限制,比如客戶端會(huì)發(fā)更頻繁的請(qǐng)求,而響應(yīng)這些請(qǐng)求的類型包括text/xml, text/plain, text/json, text/javascript.
整個(gè)Ajax的操作過(guò)程分為七步:
1.A client event occurs
2.An XMLHttpRequest object is created
3.The XMLHttpRequest object is configured
4.The XMLHttpRequest object makes an async. request
5.The ValidateServlet returns an XML document containing the result
6.The XMLHttpRequest object calls the callback() function and processes the result
7.The HTML DOM is updated
我們分別來(lái)看看這七個(gè)步驟是怎么做的: 1. A client event occurs,
<input type="text"
size="20"
id="userid"
name="id"
onkeyup="validateUserId();">
比如我們手頭上有這樣一段Javascript的代碼: 這是一個(gè)ID為userid的文本框,里面包含了一個(gè)Javascript的函數(shù),當(dāng)我們?cè)谖谋究蚶锎蛉胍粋€(gè)英文字母時(shí),會(huì)激發(fā)onkeyup的事件,從而激發(fā)validateUserId的Javascript的函數(shù).
2.An XMLHttpRequest object is created
var req;
function initRequest() {
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
} else if (window.ActiveXObject) {
isIE = true;
req = new ActiveXObject("Microsoft.XMLHTTP");
}
}
function validateUserId() {
initRequest();
req.onreadystatechange = processRequest;
if (!target) target = document.getElementById("userid");
var url = "validate?id=" + escape(target.value);
req.open("GET", url, true);
req.send(null);
}
validateUserId的Javascript的函數(shù)調(diào)用initRequest函數(shù)生成XMLHttpRequest對(duì)象, 大家注意到在initRequest函數(shù)里面有兩種生成XMLHttpRequest的方法,這是針對(duì)不同的瀏覽器的做法,對(duì)于Mozilla,我們可以直接使用"new XMLHttpRequest()”, 而對(duì)于IE,我們需要生成ActiveX對(duì)象.
3.The XMLHttpRequest object is configured
rvalidateUserId的Javascript的函數(shù)包含一句req.onreadystatechange = processRequest; 這是通過(guò)設(shè)定XMLHttpRequest對(duì)象里面的onreadystatechange特性為回調(diào)函數(shù).
4.The XMLHttpRequest object makes an async. request
if (!target) target = document.getElementById("userid");
var url = "validate?id=" + escape(target.value);
req.open("GET", url, true);
req.send(null);
然后XMLHttpRequest調(diào)用open方法和服務(wù)器交流, open方法有三個(gè)參數(shù), HTTP方法是Get還是Post, 服務(wù)器端的URL, 方式采取異步還是同步.
5.The ValidateServlet returns an XML document containing the result
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String targetId = request.getParameter("id");
if ((targetId != null) && !accounts.containsKey(targetId.trim())) {
response.setContentType("text/xml ");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write("<valid>true</valid>");
} else {
response.setContentType("text/xml ");
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write("<valid>false</valid>");
}
}
然后是服務(wù)器端ValidateServlet的響應(yīng),首先Content type設(shè)為text/xml, Cache-Control設(shè)為no-cache, 最后會(huì)返回true或者false的xml格式響應(yīng).
6.The XMLHttpRequest object calls the callback() function and processes the result
function processRequest() {
if (req.readyState == 4) {
if (req.status == 200) {
var message = ...;
現(xiàn)在控制交回給客戶端, 由于我們?cè)O(shè)定了回調(diào)函數(shù)為processRequest, 那么當(dāng)響應(yīng)從服務(wù)器端回到客戶端瀏覽器,就激發(fā)了processRequest函數(shù), 我們?cè)趐rocessRequest函數(shù)中檢查XMLHttpRequest對(duì)象的readyState狀態(tài)是否為4和status狀態(tài)是否為200,如果兩者同時(shí)成立,就代表服務(wù)器端的數(shù)據(jù)已經(jīng)成功返回給客戶端,那么就可以執(zhí)行下面的處理.
7.The HTML DOM is updated.
接收完服務(wù)器端傳回來(lái)的數(shù)據(jù)后,瀏覽器開(kāi)始著手顯示接收回的數(shù)據(jù).
我們通過(guò)頁(yè)面里面的<div>元素來(lái)唯一的表示一個(gè)對(duì)象給DOM的API使用. 比如確定html頁(yè)面某一處的需要顯示的信息文本對(duì)象,我們可以使用userIdMessage唯一的標(biāo)簽來(lái)做引用給DOM的API使用. 如下面這段代碼:
23.<body>
24. <div id="userIdMessage"></div>
25.</body>
一但你有了唯一確定的引用,你就可以使用DOM的API對(duì)其進(jìn)行隨心所欲的操作,如屬性的修改等等,比如下面這段代碼:
1. <script type="text/javascript">
2. function setMessageUsingDOM(message) {
3. var userMessageElement = document.getElementById("userIdMessage");
4. var messageText;
5. if (message == "false") {
6. userMessageElement.style.color = "red";
7. messageText = "Invalid User Id";
8. } else {
9. userMessageElement.style.color = "green";
10. messageText = "Valid User Id";
11. }
12. var messageBody = document.createTextNode(messageText);
13. // if the messageBody element has been created simple replace it otherwise
14. // append the new element
15. if (userMessageElement.childNodes[0]) {
16. userMessageElement.replaceChild(messageBody,
17. userMessageElement.childNodes[0]);
18. } else {
19. userMessageElement.appendChild(messageBody);
20. }
21.}
22.</script>
23.<body>
24. <div id="userIdMessage"></div>
25.</body>
在這里javascript通過(guò)了getElementById方法得到了userIdMessage對(duì)象,然后對(duì)服務(wù)器端返回的數(shù)據(jù)進(jìn)行對(duì)比,如果值是true,在userIdMessage里添加文本"Valid User Id", 如果值是false,則在userIdMessage里添加文本"Invalid User Id".
大概就是這樣的一個(gè)狀況,那么在Ajax里面的XMLHttpRequest還有很多方法和屬性, 包括:
方法:
• open(“HTTP method”, “URL”, syn/asyn)
> Assigns HTTP method, destination URL, mode
• send(content)
> Sends request including string or DOM object data
• abort()
> Terminates current request
• getAllResponseHeaders()
> Returns headers (labels + values) as a string
• getResponseHeader(“header”)
> Returns value of a given header
• setRequestHeader(“label”,”value”)
> Sets Request Headers before sending
屬性:
• onreadystatechange
> Set with an JavaScript event handler that fires at each
change
• readyState – current status of request
> 0 = uninitialized
> 1 = loading
> 2 = loaded
> 3 = interactive (some data has been returned)
> 4 = complete
• status
> HTTP Status returned from server: 200 = OK
• responseText
> String version of data returned from the server
• responseXML
> XML document of data returned from the server
• statusText
> Status text returned from server
Posted at 05:22PM Jul 10, 2007 by Benny Luo