1. 傳統交互方式的弊端:
瀏覽器<-->請求/響應<-->服務器
客戶端(瀏覽器)從服務器加載網頁完畢後,網頁中的內容如果需要更改,那麼就必須讓瀏覽器重新發送一次請求到服務器,服務器接收請求並處理完畢後會把一個完整的網頁返回給客戶端(瀏覽器),
每次操作都必須返回整個頁面,帶寬,響應速度都有影響的。
2. AJAX交互方式:
AJAX<-->請求/響應<-->服務器
網頁中的內容如果需要更改,不使用瀏覽器發送請求,而是使用JavaScript中的XMLHttpRequest(及Ajax對象)對象發送請求到服務器,服務器接收請求並處理完畢後只返回頁面需要的內容,XMLHttpRequest對象接收服務器返回的內容,程序員需要手動(javascript)的把內容更新到頁面中。
3. 什麼是ajax
ajax解決了傳統方法的缺陷。AJAX 是一種用於創建快速動態網頁的技術。通過在後臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新(不重新加載整個網頁的情況下,對網頁的某部分進行更新,提高用戶的使用體驗。
4. 哪些場景需要使用ajax ?
需要局部刷新的頁面(要求:至少說出4個)
- 瀏覽器地圖搜索
- 自動提示:Google Suggest 使用 AJAX 創造出動態性極強的 web 界面:當您在谷歌的搜索框輸入關鍵字時,JavaScript 會把這些字符發送到服務器,然後服務器會返回一個搜索建議的列表。3
- 用戶名重複檢查:用戶註冊時,檢查用戶名是否存在,及時給用戶反饋;4
- 郵箱提示:WEB版郵箱系統,當有新郵件到底服務器,瀏覽器不用刷新頁面也知道是否有新郵件;5
- 無刷新分頁:顯示數據列表,用戶點擊下一頁數據,整個頁面不會刷新,只把下一頁的數據更新到頁面中;6
- 購物車:用戶點擊添加到購物車後,能繼續進行其他操作,而購物車的數據存儲服務器端;=
- 用戶登錄:用戶登錄的數據通過AJAX傳輸到後臺,如果登錄失敗直接在當前登錄頁面提示用戶,而不用刷新整個頁面;
如果應用中的頁面需要局部刷新並且需要與服務器交互,那麼就可以使用AJAX;
- 視頻網站
- 股票網站(輪詢)
祕訣:瀏覽網站的時候,留心觀察很多頁面未刷新,但是頁面中的內容被更改了,這些都是AJAX使用場景; 99%的網站都會用到Ajax。
5. 同步和異步
同步是指:發送方發出數據後,等接收方發回響應以後才發下一個數據包。(提交請求->等待服務器處理->處理完畢返回 這個期間客戶端瀏覽器不能幹任何事)
異步是指:發送方發出數據後,不等接收方發回響應,接着發送下個數據包。(請求通過事件觸發->服務器處理(這時瀏覽器仍然可以作其他事情)->處理完畢)
6.ajax學習:
1:一個事件 onreadystatechange
2:2個狀態 status readyState
3:三個方法 open send setRequestHeader
onreadystatechange,存儲函數(或函數名),每當 readyState 屬性改變時,就會調用該函數。
status HTTP響應狀態
200: "OK" 請求成功
404: "NOT FOUND" 沒有找到對應資源
500:"Server Error" 服務器端錯誤
readyState
存有 XMLHttpRequest對象的請求狀態。從 0 到 4 發生變化。
0: 請求未初始化 未創建
1: 服務器連接已建立 open()方法
2: 請求已接收 send()方法
3: 請求在服務器處理中
4: 請求已完成,且響應已就緒 ,響應完畢
open(method,url,async)
創建請求,並且規定請求的類型、URL 以及是否異步處理請求。
method:請求的類型;GET 或 POST
url:文件在服務器上的位置
async:true(異步),false(同步)
send(string) 將請求發送到服務器。
string:僅用於 POST 請求,字符串必須服務器URL編碼格式(列如:param1=value1¶m2=value2);
setRequestHeader(header,value)。 添加額外的請求頭信息,post提交必須使用。
向請求添加 HTTP 頭。
header: 規定頭的名稱
value: 規定頭的值
注意:該方法必須在open與send之間調用;
原因:
1、open之後,open是創建一個請求,或者理解爲請求的基本準備,如果沒有請求,何來設置請求頭信息;
2、send之前,send是發送一個請求,請求會把當前請求的頭信息進行發送,發送後設置頭信息無效;
7 Ajax正確寫代碼流程
Ajax檢查用戶名是否重複
register.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action="" method="post"> 用戶名:<input type="text" name="username" onblur="checkName(this)"/><span id="msg"></span><br/><br/> </form> <input type="button" id="register" value="註冊"/> </body> <script type="text/javascript"> var ajax; function createAjax(){ if(window.XMLHttpRequest){ ajax = new XMLHttpRequest; }else{ //低版本ie瀏覽器 ajax = new ActiveXObject("Microsoft.XMLHTTP"); } } function checkName(ele) { var username = ele.value; //1. 獲取ajax對象 ajax = createAjax(); //2.以異步的方式發出get請求 //ajax.open("GET","checkNameServlet?username="+username+"&flag="+Math.random(),true); ajax.open("POST","checkNameServlet",true); //3. 設置請求頭 ajax.setRequestHeader("Context-type","application/x-www-from-urlencoded"); //4. 編寫事件函數 ajax.onreadystatechange = function() { if(ajax.readyState==4 && ajax.status==200){ var data = ajax.responseText; if(data == "true"){ document.getElementById("msg").innerHTML="<font style='color:green'>恭喜您,獲得一個新賬號</font>"; document.getElementById("register").disabled = false;//註冊按鈕狀態可用 }else{ //console.log("用戶名重複"); document.getElementById("msg").innerHTML="<font style='color:red'>用戶名重複</font>"; document.getElementById("register").disabled = true;//註冊按鈕狀態禁用 } } } //get發送請求 //ajax.send(); //post發送請求 ajax.send("username="+username); } </script> </html>
CheckNameServlet.java
@WebServlet("/checkServlet") public class CheckNameServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); String username = request.getParameter("username"); username = new String(username.getBytes(),"UTF-8"); System.out.println(username+"----------"); //後臺打印布爾值,前臺還是獲取字符串。 if(username.equals("admin")) { response.getWriter().print(false);//註冊失敗 }else{ response.getWriter().print(true);//註冊成功 } } }
8. jquery省市
City.java
package com.gs.domain; public class City { private Long id; private String name; private City parent; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public City getParent() { return parent; } public void setParent(City parent) { this.parent = parent; } public City(Long id, String name, City parent) { super(); this.id = id; this.name = name; this.parent = parent; } public City() { super(); // TODO Auto-generated constructor stub } }
CityUtils.java
package com.gs.tools; import java.util.ArrayList; import java.util.List; import com.gs.domain.City; public class CityUtils { static List<City> parentCitys = new ArrayList<>(); static List<City> childrenCitys = new ArrayList<>(); static { Long id=1L; City parent = new City(id++,"安徽省",null); parentCitys.add(parent); City child = new City(id++,"安慶市",parent); childrenCitys.add(child); child = new City(id++,"合肥市",parent); childrenCitys.add(child); parent = new City(id++,"浙江省",null); parentCitys.add(parent); child = new City(id++,"寧波市",parent); childrenCitys.add(child); child = new City(id++,"湖州市",parent); childrenCitys.add(child); child = new City(id++,"溫州市",parent); childrenCitys.add(child); parent = new City(id++,"江蘇省",null); parentCitys.add(parent); child = new City(id++,"南京市",parent); childrenCitys.add(child); child = new City(id++,"蘇州市",parent); childrenCitys.add(child); child = new City(id++,"無錫市",parent); childrenCitys.add(child); } public static List<City> getParentCitys() { return parentCitys; } public static List<City> getChildrenCitys(Long parentId) { List<City> temp = new ArrayList<>();//臨時存儲的集合 for(City i :childrenCitys) { if(i.getParent().getId().equals(parentId)) { temp.add(i); } } return temp; } }
SelectCity.java
@WebServlet("/selectcity") public class SelectCity extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/json;charset=utf-8"); Long id = new Long(request.getParameter("parentid")); List<City> childrenCitys = CityUtils.getChildrenCitys(id); JSON json = JSONSerializer.toJSON(childrenCitys); System.out.println(json); response.getWriter().print(json); } }
SelectProvince.java
@WebServlet("/selectprovince") public class SelectProvince extends HttpServlet { private static final long serialVersionUID = 1L; protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/json;charset=utf-8");//設置響應類型 List<City> parentCitys = CityUtils.getParentCitys(); //將集合轉換爲json對象 JSON json = JSONSerializer.toJSON(parentCitys); response.getWriter().print(json); } }
provincecity.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>二級聯動</title> <script type="text/javascript" src="js/jquery-2.1.3.js"></script> </head> <body> 省:<select id="province"></select> 市:<select id="city"></select> </body> <script type="text/javascript"> $(function(){ $.get("selectprovince",null,function(data){ //i 索引從0開始,obj==this 代表當前 $(data)—— json數據。 $(data).each(function(i,obj){ $("#province").append("<option value='"+obj.id+"'>"+obj.name+"</option>"); }); }); $("#province").change(function(){ $("#city").empty(); var data ={"parentid":$("#province option:selected").val()}; //發請求 $.get("selectcity",data,function(data){ $(data).each(function(i,obj) { $("#city").append("<option >"+obj.name+"</option>"); }); }); }); }) </script> </html>