Ajax入門與應用
阿新 • • 發佈:2018-12-14
一、Ajax介紹
1. ajax是什麼? * asynchronous javascript and xml:非同步的js和xml * 它能使用js訪問伺服器,而且是非同步訪問! * 伺服器給客戶端的響應一般是整個頁面,一個html完整頁面!但在ajax中因為是區域性重新整理,那麼伺服器就不用再響應整個頁面!而只是資料! > text:純文字 > xml:大家都熟悉!!! > json:它是js提供的資料互動格式,它在ajax中最受歡迎! 2. 非同步互動和同步互動 * 同步: > 發一個請求,就要等待伺服器的響應結束,然後才能發第二個請求!中間這段時間就是一個字“卡” > 重新整理的是整個頁面! * 非同步: > 發一個請求後,無需等待伺服器的響應,然後就可以發第二個請求! > 可以使用js接收伺服器的響應,然後使用js來區域性重新整理! 3. ajax應用場景 * 百度的搜尋框 * 使用者註冊時(校驗使用者名稱是否被註冊過) 4. ajax的優缺點 優點: * 非同步互動:增強了使用者的體驗! * 效能:因為伺服器無需再響應整個頁面,只需要響應部份內容,所以伺服器的壓力減輕了! 缺點: * ajax不能應用在所有場景! * ajax無端的增多了對伺服器的訪問次數,給伺服器帶來了壓力!
二、非同步請求四步操作
ajax傳送非同步請求(四步操作) 1. 第一步(得到XMLHttpRequest) * ajax其實只需要學習一個物件:XMLHttpRequest,如果掌握了它,就掌握了ajax!!! * 得到XMLHttpRequest > 大多數瀏覽器都支援:var xmlHttp = new XMLHttpRequest(); > IE6.0:var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); > IE5.5以更早版本的IE:var xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); * 編寫建立XMLHttpRequest物件的函式 function createXMLHttpRequest() { try { return new XMLHttpRequest(); } catch(e) { try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) { alert("哥們兒,你用的是什麼瀏覽器啊?"); throw e; } } } } 2. 第二步(開啟與伺服器的連線) * xmlHttp.open():用來開啟與伺服器的連線,它需要三個引數: > 請求方式:可以是GET或POST > 請求的URL:指定伺服器端資源,例如;/day23_1/AServlet > 請求是否為非同步:如果為true表示傳送非同步請求,否則同步請求! * xmlHttp.open("GET", "/day23_1/AServlet", true); 3. 第三步(傳送請求) * xmlHttp.send(null):如果不給可能會造成部份瀏覽器無法傳送! > 引數:就是請求體內容!如果是GET請求,必須給出null。 4. 第四步() * 在xmlHttp物件的一個事件上註冊監聽器:onreadystatechange * xmlHttp物件一共有5個狀態: > 0狀態:剛建立,還沒有呼叫open()方法; > 1狀態:請求開始:呼叫了open()方法,但還沒有呼叫send()方法 > 2狀態:呼叫完了send()方法了; > 3狀態:伺服器已經開始響應,但不表示響應結束了! > 4狀態:伺服器響應結束!(通常我們只關心這個狀態!!!) * 得到xmlHttp物件的狀態: > var state = xmlHttp.readyState;//可能是0、1、2、3、4 * 得到伺服器響應的狀態碼 > var status = xmlHttp.status;//例如為200、404、500 * 得到伺服器響應的內容1 > var content = xmlHttp.responseText;//得到伺服器的響應的文字格式的內容 > var content = xmlHttp.responseXML;//得到伺服器的響應的xml響應的內容,它是Document物件了! xmlHttp.onreadystatechange = function() {//xmlHttp的5種狀態都會呼叫本方法 if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {//雙重判斷:判斷是否為4狀態,而且還要判斷是否為200 // 獲取伺服器的響應內容 var text = xmlHttp.responseText; } }; 5. 傳送POST請求(如果傳送請求時需要帶有引數,一般都用POST請求) * open:xmlHttp.open("POST" ....); * 新增一步:設定Content-Type請求頭: > xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); * send:xmlHttp.send("username=zhangSan&password=123");//傳送請求時指定請求體
三、案例
案例一、驗證使用者名稱是否存在
============================Ajax.jsp <script type="text/javascript"> window.onload = function(){ //獲取文字 var username = document.getElementById("usernameEle"); //聚焦事件監聽 username.onblur = function(){ //建立非同步更新物件 var xmlHttp = createXMLHttpRequest(); //與伺服器建立連線 xmlHttp.open("POST","<c:url value='/ValidateUsernameJudge'/>",true); //設定請求頭 xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //傳送請求 xmlHttp.send("username="+username.value); //設定事件監聽 xmlHttp.onreadystatechange = function(){ //雙重判斷 if(xmlHttp.readyState == 4 && xmlHttp.status == 200){ //狀態正確獲取響應內容 var text = xmlHttp.responseText; var span = document.getElementById("errorusername"); if(text == "1"){ span.innerHTML = "使用者名稱已存在,請重新輸入!"; }else{ span.innerHTML = ""; } } }; }; }; function createXMLHttpRequest(){ try{ return new XMLHttpRequest(); }catch(e){ try{ return new ActiveXObject("Msxml2.XMLHTTP"); }catch(e){ try{ return new ActiveXObject("Microsoft.XMLHTTP"); }catch(e){ alert("非同步物件建立失敗"); throw e ; } } } } <h2> 非同步判斷使用者名稱是否存在 </h2> <form action="/ValidateUsernameJudge" method="post"> username:<input type="text" id="usernameEle" name="username"/><span id="errorusername"></span><br> password:<input type="password" id="passwordEle" name="password"/><br> <input type="submit" value="註冊"/> </form> ============================ValidateUsernameJudge.java public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); /* * 1. 獲取引數username * 2. 判斷是否為itcast * 3. 如果是:響應1 * 4. 如果不是:響應0 */ String username = request.getParameter("username"); if(username.equalsIgnoreCase("itcast")) { response.getWriter().print("1"); } else { response.getWriter().print("0"); } }
案例二、省市聯動china.xml
===============================ajax.jsp
<script type="text/javascript">
function createXMLHttpRequest() {
try {
return new XMLHttpRequest();//大多數瀏覽器
} catch (e) {
try {
return ActvieXObject("Msxml2.XMLHTTP");//IE6.0
} catch (e) {
try {
return ActvieXObject("Microsoft.XMLHTTP");//IE5.5及更早版本
} catch (e) {
alert("哥們兒,您用的是什麼瀏覽器啊?");
throw e;
}
}
}
}
/*
* 1. 在文件載入完畢時傳送請求,得到所有省份名稱,顯示在<select name="province"/>中
* 2. 在選擇了新的省份時,傳送請求(引數為省名稱),得到xml文件,即<province>元素
* 解析xml文件,得到其中所有的<city>,再得到每個<city>元素的內容,即市名,使用市名生成<option>,插入到<select name="city">元素中
*/
window.onload = function() {
/*
ajax四步,請求ProvinceServlet,得到所有省份名稱
使用每個省份名稱建立一個<option>元素,新增到<select name="province">中
*/
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("GET", "<c:url value='/ProvinceServlet'/>", true);
xmlHttp.send(null);
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
// 獲取伺服器的響應
var text = xmlHttp.responseText;
// 使用逗號分隔它,得到陣列
var arr = text.split(",");
// 迴圈遍歷每個省份名稱,每個名稱生成一個option物件,新增到<select>中
for(var i = 0; i < arr.length; i++) {
var op = document.createElement("option");//建立一個指名名稱元素
op.value = arr[i];//設定op的實際值為當前的省份名稱
var textNode = document.createTextNode(arr[i]);//建立文字節點
op.appendChild(textNode);//把文字子節點新增到op元素中,指定其顯示值
document.getElementById("p").appendChild(op);
}
}
};
/*
第二件事情:給<select name="province">新增改變監聽
使用選擇的省份名稱請求CityServlet,得到<province>元素(xml元素)!!!
獲取<province>元素中所有的<city>元素,遍歷之!獲取每個<city>的文字內容,即市名稱
使用每個市名稱建立<option>元素新增到<select name="city">
*/
var proSelect = document.getElementById("p");
proSelect.onchange = function() {
var xmlHttp = createXMLHttpRequest();
xmlHttp.open("POST", "<c:url value='/CityServlet'/>", true);
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.send("pname=" + proSelect.value);//把下拉列表中選擇的值傳送給伺服器!
xmlHttp.onreadystatechange = function() {
if(xmlHttp.readyState == 4 && xmlHttp.status == 200) {
/*
把select中的所有option移除(除了請選擇)
*/
var citySelect = document.getElementById("c");
// 獲取其所有子元素
var optionEleList = citySelect.getElementsByTagName("option");
// 迴圈遍歷每個option元素,然後在citySelect中移除
while(optionEleList.length > 1) {//子元素的個數如果大於1就迴圈,等於1就不迴圈了!
citySelect.removeChild(optionEleList[1]);//總是刪除1下標,因為1刪除了,2就變成1了!
}
var doc = xmlHttp.responseXML;
// 得到所有名為city的元素
var cityEleList = doc.getElementsByTagName("city");
// 迴圈遍歷每個city元素
for(var i = 0; i < cityEleList.length; i++) {
var cityEle = cityEleList[i];//得到每個city元素
var cityName;
// 獲取市名稱
if(window.addEventListener) {//處理瀏覽器的差異
cityName = cityEle.textContent;//支援FireFox等瀏覽器
} else {
cityName = cityEle.text;//支援IE
}
// 使用市名稱建立option元素,新增到<select name="city">中
var op = document.createElement("option");
op.value = cityName;
// 建立文字節點
var textNode = document.createTextNode(cityName);
op.appendChild(textNode);//把文字節點追加到op元素中
//把op新增到<select>元素中
citySelect.appendChild(op);
}
}
};
};
};
</script>
<h1>省市聯動</h1>
<select name="province" id="p">
<option>===請選擇省===</option>
</select>
<select name="city" id="c">
<option>===請選擇市===</option>
</select>
===============================ProvinceServlet.java
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
/*
* 響應所有省份名稱,使用逗號分隔!
*/
/*
* 1. Document物件
* * 建立解析器物件
* * 呼叫解析器的讀方法,傳遞一個流物件,得到Document
*/
try {
SAXReader reader = new SAXReader();
InputStream input = this.getClass().getResourceAsStream("/china.xml");
Document doc = reader.read(input);
/*
* 查詢所有province的name屬性,得到一堆的屬性物件
* 迴圈遍歷,把所有的屬性值連線成一個字串,傳送給客戶端
*/
List<Attribute> arrList = doc.selectNodes("//province/@name");
StringBuilder sb = new StringBuilder();
for(int i = 0; i < arrList.size(); i++) {
sb.append(arrList.get(i).getValue());//把每個屬性的值存放到sb中。
if(i < arrList.size() - 1) {
sb.append(",");
}
}
response.getWriter().print(sb);
} catch(Exception e) {
throw new RuntimeException(e);
}
}
===============================CityServlet.java
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
response.setContentType("text/xml;charset=utf-8");//注意:傳送xml這裡要修改!!!
/*
* 獲取省份名稱,載入該省對應的<province>元素!
* 把元素轉換成字串傳送給客戶端
*/
/*
* 1. 獲取省份的名稱
* 2. 使用省份名稱查詢到對應的<province>元素
* 3. 把<province>元素轉換成字串,傳送!
*/
try {
/*
* 得到Document
*/
SAXReader reader = new SAXReader();
InputStream input = this.getClass().getResourceAsStream("/china.xml");
Document doc = reader.read(input);
/*
* 獲取引數
*/
String pname = request.getParameter("pname");//獲取省份名稱
Element proEle = (Element) doc.selectSingleNode("//province[@name='" + pname + "']");
String xmlStr = proEle.asXML();//把元素轉換成字串
response.getWriter().print(xmlStr);
} catch(Exception e) {
throw new RuntimeException(e);
}
}