day16_ajax學習筆記

一、什麼是Ajax

Ajax( Asynchronous JavaScript And XML ):指異步 JavaScript 及 XML。 不是一種新的編程語言 ,而是一種用於創建更好更快以及交互性更強的 Web 應用程序的技術,是基於JavaScript、XML、HTML、CSS的新用法。

Ajax:只刷新局部頁面的技術。包括以下幾種技術:

  • JavaScript:更新局部的網頁。
  • XML:一般用於請求數據和響應數據的封裝。
  • XMLHttpRequest對象:發送請求到服務器並獲得返回結果(瀏覽器內核創建的)。
  • CSS:美化頁面樣式。
  • 異步:發送請求後不等待返回結果,由回調函數處理結果。

JavaScript 中 XMLHttpRequest對象是整個Ajax技術的核心,它提供了異步發送請求的能力。

構造方法:   不同瀏覽器,甚至相同瀏覽器的不同版本,獲取該對象的方式是不同的。

var xmlhttp;
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
    xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}

方法:   open()  該方法有3個參數,"get|post","url?name=tom","true|false",默認爲true。   send() 發送請求,可以帶參數 或 null。   setRequestHeader() 設置請求消息頭。

屬性:   readyState  類型爲short,只讀   responseText  類型爲String,只讀   responseXML  類型爲Document,只讀(一般不用)   status  類型爲short,只讀

事件處理器:   onreadystatechange

二、常用方法

  • open(method, URL, async) 建立與服務器的連接   method參數:指請求的HTTP方法,典型的值是GET或POST   URL參數:指請求的地址   async參數:指是否使用異步請求,其值爲true或false,默認值是true,一般這個參數不寫
  • send(content) 發送請求   content參數:指請求的參數
  • setRequestHeader(header, value) 設置請求的頭信息

三、常用屬性

  • onreadystatechange: 指定回調函數
  • readyState: XMLHttpRequest的狀態信息(客戶端:瀏覽器) 就緒狀態碼說明 0 XMLHttpRequest對象沒有完成初始化,即:剛剛創建。 1 XMLHttpRequest對象開始發送請求,即:調用了open方法,但還沒有調用send方法。請求還沒有發出。 2 XMLHttpRequest對象的請求發送完成,即:send方法已經調用,數據已經提交到服務器,但沒有任何響應。 3 XMLHttpRequest對象開始讀取響應,還沒有結束,即:收到了所有的響應消息頭,但正文還沒有完全收到。 4 XMLHttpRequest對象讀取響應結束,即:一切都收到了
  • status: HTTP的狀態碼(服務器端) 狀態碼說明 200 服務器響應正常 400 無法找到請求的資源 403 沒有訪問權限 500 服務器內部錯誤
  • responseText: 獲得響應的文本內容
  • responseXML: 獲得響應的XML文檔對象 documednt

注:客戶端就緒狀態碼是4,且服務端狀態碼是200,纔可以處理服務器數據。

示例代碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/myJS.js"></script>
<title>Insert title here</title>
</head>
    <script type="text/javascript">
        // 1、獲取XMLHttpRequest對象
        var req = getXMLHttpRequest();
        // 4、處理響應結果
        req.onreadystatechange = function() {
            // alert(req.readyState); // 查看客戶器端就緒狀態碼
            if (req.readyState == 4) {
                // alert(req.status); // 查看服務器端響應狀態碼
                if (req.status == 200) { // 說明服務器響應一切正常
                    alert(req.responseText);
                }
            }
        }
        // 2、建立一個連接
        req.open("get", "${ pageContext.request.contextPath }/servlet/servletDemo1");
        // 3、發送請求
        req.send(null);
    </script>
<body>
</body>
</html>

使用Ajax驗證用戶名是否存在的實現步驟:

  1. 使用文本框的onblur事件(失去焦點事件)
  2. 使用Ajax技術實現異步交互 a) 獲取用戶名 a) 創建 XMLHttpRequest 對象 b) 處理響應結果,創建回調函數,根據響應狀態動態更新頁面 c) 建立一個連接 d) 發送請求

示例代碼如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/myJS.js"></script>
<title>Insert title here</title>
    <script type="text/javascript">
        function ckName() {
            // 獲取用戶名對象
            var name = document.getElementsByTagName("input")[0];
            // 創建XMLHttpRequest對象
            var xhr = getXMLHttpRequest();
            // 處理響應結果,創建回調函數,根據響應狀態動態更新頁面
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) { // 說明客戶端請求一切正常
                    if (xhr.status == 200) { // 說明服務器響應一切正常
                        // alert(xhr.responseText); // 得到響應結果
                        var msg = document.getElementById("msg");
                        if (xhr.responseText == "true") {
                            // msg.innerText = "用戶名已存在";
                            msg.innerHTML = "<font color='red'>該用戶名已存在</font>";
                        } else {
                            msg.innerHTML = "<font color='green'>該用戶名可以使用</font>";
                        }
                    }
                }
            }           
            // 建立一個連接
            xhr.open("get", "${ pageContext.request.contextPath }/servlet/ckNameServlet?name=" + name.value + "&time=" + new Date().getTime());
            // 發送請求
            xhr.send(null);
        }
    </script>
</head>
<body>
    用戶名:<input type="text" name="userName" onblur="ckName()"/><span id="msg" ></span></br>
    密碼:<input type="password" name="pwd" /></br>
</body>
</html>

驗證用戶名是否存在改進代碼版本(該種方式,使得網頁的標籤很乾淨,感覺不到調用事件了):

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<script type="text/javascript" src="${ pageContext.request.contextPath }/js/myJS.js"></script>
<title>Insert title here</title>
    <script type="text/javascript">
        window.onload = function() {
            var nameElement = document.getElementsByName("userName")[0];
            nameElement.onblur = function() {
                var name = this.value; // this等價於nameElement
                // 創建XMLHttpRequest對象
                var xhr = getXMLHttpRequest();
                // 處理響應結果,創建回調函數,根據響應狀態動態更新頁面
                xhr.onreadystatechange = function() {
                    if (xhr.readyState == 4) { // 說明客戶端請求一切正常
                        if (xhr.status == 200) { // 說明服務器響應一切正常
                            // alert(xhr.responseText); // 得到響應結果
                            var msg = document.getElementById("msg");
                            if (xhr.responseText == "true") {
                                // msg.innerText = "用戶名已存在";
                                msg.innerHTML = "<font color='red'>該用戶名已存在</font>";
                            } else {
                                msg.innerHTML = "<font color='green'>該用戶名可以使用</font>";
                            }
                        }
                    }
                }           
                // 建立一個連接
                xhr.open("get", "${pageContext.request.contextPath }/servlet/ckNameServlet?name=" + name + "&time=" + new Date().getTime());
                // 發送請求
                xhr.send(null);
            }
        }
    </script>
</head>
<body>
    用戶名:<input type="text" name="userName" /><span id="msg" ></span></br>
    密碼:<input type="password" name="pwd" /></br>
</body>
</html>

四、案例1:實現郵箱驗證

  • my.js
// 獲取XMLHttpRequest對象
function getXMLHttpRequest() {
    var xmlhttp;
    if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else { // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    return xmlhttp;
}
  • register.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<script type="text/javascript" src="${pageContext.request.contextPath }/js/my.js"></script>
<head>
<title>bookStore註冊頁面</title>
<%--導入css --%>
<link rel="stylesheet" href="css/main.css" type="text/css" />
<script type="text/javascript">
    function changeImage() {
        document.getElementById("img").src = "${pageContext.request.contextPath}/imageCode?time="
                + new Date().getTime();
    }
    // 驗證郵箱是否存在
    function ckEmail() {
        // 得到郵箱對象
        var email = document.getElementByName("email")[0];
        // 創建XMLHttpRequest對象
        var xhr = getXMLHttpRequest();
        // 處理響應結果,創建回調函數,根據響應狀態動態更新頁面
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4) {
                if (xhr.status == 200) {
                    alert(xhr.responseText); // 得到響應結果
                    // 得到郵箱的font標籤
                    var font = document.getElementsByTagName("font")[0];
                    if (xhr.responseText == "true") {
                        font.innerHTML = "此郵箱已被使用";
                        font.style.color = "red";
                    } else {
                        font.innerHTML = "此郵箱可以使用";
                        font.style.color = "green";
                    }
                }
            }
        }
        // 建立一個連接
        xhr.open("get", "${pageContext.request.contextPath}/servlet/ckEmailServlet?email=" + email.value + "&time=" + new Date().getTime());
        // 發送請求
        xhr.send(null);
    }
</script>
</head>
<body class="main">
    <%@include file="head.jsp"%>
    <%--導入頭 --%>
    <%@include file="menu_search.jsp"%><%--導入導航條與搜索 --%>
    <div id="divcontent">
        <form action="${pageContext.request.contextPath}/register.jsp"
            method="post">
            <table width="850px" border="0" cellspacing="0">
                <tr>
                    <td style="padding:30px">
                        <h1>新會員註冊</h1>
                        <table width="70%" border="0" cellspacing="2" class="upline">
                            <tr>
                                <td style="text-align:right; width:20%">會員郵箱:</td>
                                <td style="width:40%">
                                <input type="text" class="textinput"
                                    name="email" onblur="ckEmail()"/></td>
                                <td><font color="#999999">請輸入有效的郵箱地址</font></td>
                            </tr>
.......
</body>
</html>
  • CkEmailServlet.java
package com.itheima.web.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CkEmailServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        PrintWriter out = response.getWriter();
        String email = request.getParameter("email");
        if ("[email protected]".equals(email)) {
            out.print(true);
        } else {
            out.print(false);
        }
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

五、案例2:搜索框顯示數據

  1. 編寫顯示數據的容器div
  2. 實現ajax響應數據 // 創建XMLHttpRequest對象 // 通過事件調用回調函數處理響應結果 // 創建一個服務器連接 // 發送請求

示例代碼如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<script type="text/javascript"
    src="${pageContext.request.contextPath}/js/my.js">
</script>
<script type="text/javascript">
    window.onload = function() {
        // 得到搜索框對象
        var searchElement = document.getElementById("name");
        // 得到父div元素對象
        var div = document.getElementById("context1");
        // 給文件框註冊按鍵彈起事件
        searchElement.onkeyup = function() { 
            // 先獲取文本框的值
            var name = this.value;
            // 如果文本框沒有數據時,就把父div隱藏,且不向服務器發送請求
            if (name == "") {
                div.style.display = "none";
                return;
            }
            // 獲得XMLHttpRequest對象
            var xhr = getXMLHttpRequest();
            // 處理結果
            xhr.onreadystatechange = function() {
                if (xhr.readyState == 4) { // 客戶端請求一 切正常
                    if (xhr.status == 200) { // 服務器響應一切正常
                        var str = xhr.responseText; // 得到服務器返回的數據
                        var ss = str.split(","); // 把字符串 1001,1002,1003 切成數組
                        var childDivs = "";
                        // 循環把數據放入子div中
                        for (var i = 0; i < ss.length; i++) {
                            childDivs += "<div onclick='writeText(this)' onmouseover='changeBackground_over(this)' onmouseout='changeBackground_out(this)'>" 
                            + ss[i] + "</div>"; // 把數組中的每個元素放到子div中
                        }
                        div.innerHTML = childDivs; // 把多個子div(childDivs)放入列表父div中
                        div.style.display = "block"; // 把列表隱藏
                    }
                }
            }
            xhr.open("get", "${ pageContext.request.contextPath}/servlet/searchBookAJAXServlet?name=" + name + "&time=" + new Date().getTime());
            xhr.send(null);
        }
    }
    // 鼠標懸浮在子div時,改變背景色
    function changeBackground_over(div) {
        div.style.backgroundColor = "gray"; // backgroundColor js中屬性的寫法,background-color css中屬性的寫法
    }
    // 鼠標離開子div時,恢復背景色
    function changeBackground_out(div) {
        div.style.backgroundColor = "";
    }
    // 填充文本到搜索框
    function writeText(div) {
        // 先得到搜索框
        var searchElement = document.getElementById("name");
        // 把div中的文本添加到搜索框中
        searchElement.value = div.innerHTML; 
        // 把父div(context1)隱藏
        div.parentNode.style.display = "none"; 
    }
</script>
<div id="divmenu">
    <a href="${pageContext.request.contextPath}/showProductByPage?category=文學">文學</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=生活">生活</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=計算機">計算機</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=外語">外語</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=經營">經管</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=勵志">勵志</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=社科">社科</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=學術">學術</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=少兒">少兒</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=藝術">藝術</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=原版">原版</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=科技">科技</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=考試">考試</a>
    <a href="${pageContext.request.contextPath}/showProductByPage?category=生活百科">生活百科</a>
    <a href="${pageContext.request.contextPath}/showProductByPage" style="color:#FFFF00">全部商品目錄</a>
</div>
<div id="divsearch">
    <form action="${pageContext.request.contextPath}/findProductBySearch"
        method="post">
        <table width="100%" border="0" cellspacing="0" >
            <tr>
                <td style="text-align:right; padding-right:220px">
                Search 
                    <input type="text" name="name" class="inputtable" 
                    id="name" autocomplete="on"/> <!-- 解決中文提交的問題 -->
                    <input type="image" src="images/serchbutton.gif"
                    border="0" style="margin-bottom:-4px">
                </td>
            </tr>
        </table>
    </form>
</div>
    <div id="context1" style="display:block; border:1px solid red; background-color:white; 
    width:128px; position:absolute; left:860px; top:135px;">
</div>

六、json對象的學習

示例代碼如下: json.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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=UTF-8">
<title>Insert title here</title>
</head>
<body>
    <script type="text/javascript">
        /* json對象有些像java的普通類對象,java是純面向對象,javascript是基於對象和事件的腳本語言。
        // java語言創建的類
        public class Person() {
            private String name;
            private int age;
            public void show() {
            }
        }
        */
        /*
        // js語言創建的類,大小寫均可,一般小寫,爲了更像一個類,這時我們大寫
        function Person() {
            var name = "tom"; // 聲明一個局部變量
            this.age = 10; // 聲明一個成員變量
            this.show = function() {
                alert(name);
            }
        }
        var p = new Person();
        document.write(p.name);
        document.write(p.age);
        p.show();
        */
        var pp = [100, true, 12.34]; // 這是一個數組
        var pp = { name:"tom", age:18, 
            show:function() {
                alert("hello json");
            } 
        }; // 這是一個json對象
        document.write(pp.name);
        document.write(pp.age);
        pp.show();
        var ppp = [ { name:"tom", age:18 }, { name:"lune", age:25 } ];
        document.write(ppp[1].name)
    </script>
</body>
</html>

JsonTest.java

package com.itheima.json;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;
import com.itheima.domain.Book;
import com.itheima.util.C3P0Util;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
public class JsonTest {
    @Test // 使用 JSONObject對象封裝對象數據
    public void test1() {
        Book b = new Book();
        b.setId("10001");
        b.setName("西遊記");
        b.setPnum(20);
        String s = JSONObject.fromObject(b).toString();
        System.out.println(s);
    }
    @Test // 使用 JSONArray對象封裝 List<Book>對象數據
    public void test2() throws SQLException {
        List<Book> list = new ArrayList<Book>();
        Book b1 = new Book();
        b1.setId("10001");
        b1.setName("西遊記");
        b1.setPnum(20);
        Book b2 = new Book();
        b2.setId("10002");
        b2.setName("三國演義");
        b2.setPnum(30);
        Book b3 = new Book();
        b3.setId("10003");
        b3.setName("水滸傳");
        b3.setPnum(40);
        list.add(b1);
        list.add(b2);
        list.add(b3);
        String s = JSONArray.fromObject(list).toString();
        System.out.println(s);
    }
    @Test // 使用 JSONArray對象封裝 List<Book>對象數據 + 使用 JsonConfig對象過濾掉不想要的數據
    public void test3() throws SQLException {
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        List<Book> list = qr.query("select * from book", new BeanListHandler<Book>(Book.class));
        JsonConfig jc = new JsonConfig();
        jc.setExcludes(new String[]{"pnum", "description", "category", "id"});
        String s = JSONArray.fromObject(list, jc).toString();
        System.out.println(s);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章