Ajax技術——與服務器通信


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">&nbsp;戶&nbsp;名:<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>&nbsp;&nbsp;&nbsp;&nbsp;碼:<input type="password" name="pwd1" id="pwd1" size="35"><br>
        確認密碼:<input type="password" name="pwd2" id="pwd2" size="35"><br>
        &nbsp;&nbsp;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("恭喜您,該用戶名沒有被注冊!"); //輸出檢測結果
    }
 %>

由於本實例比較簡單,這里沒有從數據庫中獲取用戶信息,而是將用戶信息保存在一個一維數組中。在實際項目開發時,通常情況下是從數據庫中獲取用戶信息。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM