一、什麼是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驗證用戶名是否存在的實現步驟:
- 使用文本框的
onblur事件(失去焦點事件)
- 使用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:搜索框顯示數據
- 編寫顯示數據的容器div
- 實現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); } }