1. 發送請求
Ajax可以通過XMLHttpRequest對象實現采用異步方式在后台發送請求。通常情況下,Ajax發送請求有兩種,一種是發送GET請求,另一種是發送POST請求。但是無論發送哪種請求,都需要經過以下4個步驟。
(1)初始化XMLHttpRequest對象。為了提高程序的兼容性,需要創建一個跨瀏覽器的XMLHttpRequest對象,並且判斷XMLHttpRequest對象的實例是否成功,如果不成功,則給予提示。具體代碼如下:
例1.1 發送請求。
http_request=false; if(window.XMLHttpRequest){ //非IE瀏覽器 http_request=new XMLHttpRequest(); //創建XMLHttpRequest對象 }else if(window.ActiveXObject){ //IE瀏覽器 try{ http_request=new ActiveXObject("Msxml2.XMLHTTP"); //創建XMLHttpRequest對象 }catch(e){ try{ http_request=new ActiveXObject("Microsoft.XMLHTTP"); //創建XMLHttpRequest對象 }catch(e){} } } if(!http_request){ alert("不能創建XMLHttpRequest 對象實例!"); return false; }
(2) 為XMLHttpRequest對象指定一個返回結果處理函數(即回調函數),用於對返回結果進行處理。具體代碼如下:
例1.2 設置回調函數。
http_request.onreadystatechange=getResult; //調用返回結果處理函數
注意:使用XMLHttpRequest對象的onreadystatechange屬性指定回調函數時,不能指定要傳遞的參數。如果要指定傳遞的參數,可以用以下方法:
http_request.onreadystatechange=function(){getResult(param)};
(3)創建一個與服務器的連接。在創建時,需要指定發送請求的方式(即GET或POST),以及設置是否采用異步方式發送請求。
例1.3 采用異步方式發送GET方式的請求的具體代碼如下:
http_request.open('GET',url,true);
例1.4 采用異步方式發送POST方式的請求的具體代碼如下:
http_request.open('POST',url,true);
說明:在open()方法中的url參數,可以是一個JSP頁面的URL地址,也可以是Servlet的映射地址。也就是說,請求處理頁,可以是一個JSP頁面,也可以是一個Servlet。
技巧:在指定URL參數時,最好將一個時間戳追加到該URL參數的后面,這樣可以防止因瀏覽器緩存結果而不能實時得到最新的結果。例如,可以指定URL參數為以下代碼:
String url="deal.jsp?nocache="+new Date().getTime();
(4)想服務器發送請求。XMLHttpRequest對象的send()方法可以實現向服務器發送請求,該方法需要傳遞一個參數,如果發送的是GET請求,可以將該參數設置為null;如果發送的是POST請求,可以通過該參數指定要發送的請求參數。
向服務器發送GET請求的代碼如下:
http_request.send(null); //向服務器發送請求
例1.5 向服務器發送POST請求的代碼如下:
var param="user="+form1.user.value+"&pwd="+form1.pwd.value+"&emali="+form1.email.value; //組合參數 http_request.send(param); //向服務器發送請求
需要注意的是在發送POST請求之前,還需要設置正確的請求頭。具體代碼如下:
http_request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
上面這句代碼,需要加在“http_request.send(param);”語句之前。
2. 處理服務器響應
XMLHttpRequest對象提供了兩個用來訪問服務器響應的屬性,一個是responseText屬性,返回字符串響應;另一個是responseXML屬性,返回XML響應。
2.1 處理字符串響應
字符串響應通常應用在響應不是特別復雜的情況下。例如,將響應顯示在提示對話框中,或者響應只是顯示成功或失敗的字符串。
例2.1 將字符串響應顯示到提示對話框中的回調函數的具體代碼如下:
function getResult(){ if(http_request.readyState==4){ //判斷請求狀態 if(http_request.status==200){ //請求成功,開始處理返回結果 alert(http_request.responseText); //顯示判斷結果 }else { //請求頁面有錯誤 alert("您所請求的頁面有錯誤!"); } } }
如果需要將該響應結果顯示到頁面的指定位置,也可以先在頁面的合適位置添加一個<div>或<span>標記,將設置該標記的id屬性,如div_result,然后在回調函數中應用以下代碼顯示響應結果:
document.getElementById("div_result").innerHTML=http_request.responseText;
2.2 處理XML響應
如果在服務器端需要生成特別復雜的響應,那么就需要應用XML響應。應用XMLHttpRequest對象的responseXML屬性,可以生成一個XML文檔,而且當前瀏覽器已經提供了很好的解析XML文檔對象的方法。
例2.2 保存圖書信息的XML文檔。具體代碼如下:
<?xml version="1.0" encoding="UTF-8"?> <mr> <books> <book> <title>Java Web程序開發范例寶典</title> <publisher>人民郵電出版社</publisher> </book> <book> <title>Java 范例完全自學手冊</title> <publisher>人民郵電出版社</publisher> </book> </books> </mr>
在回調函數中遍歷保存圖書信息的XML文檔,並將其顯示到頁面中的代碼如下:
function getResult(){ if(http_request.readyState==4){ if(http_request.status==200){ var xmldoc=http_request.responseXML; var str=""; for (int i = 0; i <xmldoc.getElementByTagName("book").length; i++) { var book=xmldoc.getElementByTagName("book").item(i); str=str+"《"+book.getElementByTagName("title")[0].firstChild.data+"》由“"+ book.getElementByTagName('publisher')[0].firstChild.data+"”出版<br>"; } document.getElementById("book").innerHTML=str; //顯示圖書信息 }else { alert("您所請求的頁面有錯誤!"); } } } <div id="book"></div>
通過上面的代碼獲取的XML文檔的信息如下:
《Java Web程序開發范例寶典》由“人民郵電出版社”出版
《Java 范例完全自學手冊》由“人民郵電出版社”出版
3. 一個完整的實例——檢測用戶名是否唯一
例3.1 檢測用戶名是否唯一。
(1)創建index.jsp文件,在該文件中添加一個用於收集用戶注冊信息的表單及表單元素,以及表“檢測用戶名”按鈕的圖片,並在該圖片的onclick事件中調用checkName()方法,檢測用於名是否被注冊。在頁面的合適位置添加一個用於顯示提示信息的<div>標記,並且通過CSS設置該<div>標記的樣式。關鍵代碼如下:
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <title>Insert title here</title> </head> <style type="text/css"> <!-- #toolTip{ position:absolute; //設置絕對定位 left:331px; //設置左邊距 top:39px; //設置頂邊距 width:98px; //設置寬度 height:48px; //設置高度 padding-top:45px; //設置文字與頂邊的距離 padding-left:25px; //設置文字與左邊的距離 padding-right:25px; //設置文字與右邊的距離 z-index:1; display:none; //設置默認不顯示 color:red; //設置文字的顏色 background-image:url(images/tooltip.gif); //設置背景圖片 } --> </style> <div id="toolTip"></div> <script type="text/javascript"> function createRequest(url){ http_request=false; if(window.XMLHttpRequest){ //非IE瀏覽器 http_request=new XMLHttpRequest(); //創建XMLHttpRequest對象 }else if(window.ActiveXObject){ //IE瀏覽器 try{ http_request=new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ try{ http_request=new ActiveXObject("Microsoft.XMLHTTP"); }catch(e){} } } if(!http_request){ alert("不能創建MLHttpRequest對象實例!"); return false; } http_request.onreadystatechange=getResult; //調用返回結果處理函數 http_request.open("GET", url, true); //創建與服務器的連接 http_request.send(null); //向服務器發送請求 } function getResult(){ if(http_request.readyState==4){ //判斷請求狀態 if(http_request.status==200){ //請求成功,開始處理返回結果 document.getElementById("toolTip").innerHTML=http_request.responseText; //設置提示內容 document.getElementById("toolTip").style.display="block"; //顯示提示框 }else { //請求頁面有錯誤 alert("您所請求的頁面有錯誤!"); } } } function checkUser(userName){ if(userName.value==""){ alert("請輸入用戶名!"); userName.focus(); return; }else{ createRequest('checkUser.jsp?user='+userName.value); } } </script> <body> <form method="post" action="" name="form1"> 用 戶 名:<input type="text" name="username" id="username" size="32"> <img src="images/checkBt.png" width="100" height="26" style="cursor:hand;" onclick="checkUser(form1.username);"><br> 密 碼:<input type="password" name="pwd1" id="pwd1" size="35"><br> 確認密碼:<input type="password" name="pwd2" id="pwd2" size="35"><br> E-mail:<input type="text" name="email" id="email" size="45"><br> <input type="image" name="imageField" src="images/registerBt.png"> </form> </body> </html>
(2)編寫檢測用戶名是否被注冊的處理頁checkUse.jsp,在該頁面中判斷輸入的用戶名是否注冊,並應用JSP內置對象out的println()方法輸出判斷結果。checkUser.jsp頁面的具體代碼如下:
<%@ page language="java" contentType="text/html; charset=GB18030" pageEncoding="GB18030"%> <%@ page import="java.util.*" %> <% String[] userList={"明日科技","mr","mrsoft","gao"}; //創建一個一維數據 String user=new String(request.getParameter("user").getBytes("ISO-8859-1"),"GB18030"); //獲取用戶名 防止亂碼 Arrays.sort(userList); //對數組排序 int result=Arrays.binarySearch(userList, user); if(result>-1){ out.println("很抱歉,該用戶名已被注冊!"); //輸出檢測結果 }else{ out.println("恭喜您,該用戶名沒有被注冊!"); //輸出檢測結果 } %>
由於本實例比較簡單,這里沒有從數據庫中獲取用戶信息,而是將用戶信息保存在一個一維數組中。在實際項目開發時,通常情況下是從數據庫中獲取用戶信息。