在互聯網高速發展的今天,傳統的WEB應用,對於高併發、高性能、高可靠性的要求已迫在眉睫。單線程方式的客戶端與服務端交互方式已經不能知足現階段的需求.咱們須要以異步、按需加載的方式從服務端獲取數據並及時刷新,來提升用戶體驗,因而Ajax技術誕生。javascript
Ajax (Asynchronous JavaScript and XML) 是一種Web應用客戶端技術,能夠藉助客戶端腳本(javascript)與服務端應用進行異步通信(能夠有多個線程同時與服務器交互),而且按需獲取服務端數據之後,能夠進行局部刷新,進而提升數據的響應和渲染速度。html
Ajax技術最大的優點就是底層異步,而後局部刷新,進而提升用戶體驗,這種技術如今在不少項目中都有很好的應用,例如:java
AJAX能夠僅向服務器發送並取回必要的數據,並在客戶端採用JavaScript處理來自服務器的響應。這樣在服務器和瀏覽器之間交換的數據大量減小,服務器響應的速度就更快了。但Ajax技術也有劣勢,最大劣勢是不能直接進行跨域訪問。jquery
傳統方式是web請求與響應(客戶端要等待響應結果),如圖所示:web
Ajax方式的請求與響應(關鍵是客戶端不阻塞),如圖所示:ajax
Ajax 編碼的基本步驟?(重點是ajax技術的入口-XMLHttpRequest-XHR對象)spring
第一步:基於dom事件建立XHR對象
第二步:在XHR對象上註冊狀態監聽(監聽客戶端與服務端的通信過程)
第三步:與服務端創建鏈接(指定請求方式,請求url,同步仍是異步)
第四步:發送請求(將請求數據傳遞服務端)數據庫
Ajax 編碼過程的模板代碼以下:編程
var xhr=new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4&&xhr.status==200){ console.log(xhr.responseText) } } xhr.open("GET",url,true); xhr.send(null);
第一步:建立項目module,如圖所示:json
第二步:添加Spring web依賴,代碼以下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
第三步:建立AjaxController處理客戶端請求,代碼以下:
package com.cy.pj.ajax.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class AjaxController { @RequestMapping("/doAjaxStart") public String doAjaxStart(){ return "Response Result Of Ajax Get Request 01 "; } }
第四步:在項目中static目錄下,建立一個頁面ajax-01.html,代碼以下:
html元素代碼以下:
<h1>The Ajax 01 Page</h1> <fieldset> <legend>Ajax 異步Get請求</legend> <button onclick="doAjaxStart()">Ajax Get Request</button> <span id="result">Data is Loading ...</span> </fieldset>
javascript 腳本代碼以下:
function doAjaxStart(){ //debugger//客戶端斷點(此斷點生效須要打開控制檯) //1.建立XHR對象(XmlHttpRequest)-Ajax應用的入口對象 let xhr=new XMLHttpRequest(); //2.在XHR對象上註冊狀態監聽(拿到服務端響應結果之後更新到頁面result位置) xhr.onreadystatechange=function(){//事件處理函數(客戶端與服務端通信狀態發生變化 時會執行此函數) //readyState==4表示服務端響應到客戶端數據已經接收完成. if(xhr.readyState==4){ if(xhr.status==200){//status==200表示請求處理過程沒問題 document.getElementById("result").innerHTML= xhr.responseText; } } } //3.與服務端創建鏈接(指定請求方式,請求url,異步) xhr.open("GET","http://localhost/doAjaxStart",true);//true表明異步 //4.向服務端發送請求 xhr.send(null);//get請求send方法內部不傳數據或者寫一個null //假如是異步客戶端執行完send會繼續向下執行. }
第五步:啓動Tomcat服務並進行訪問測試分析.
點擊Ajax Get Request 按鈕,檢測頁面數據更新.
第六步:啓動及訪問過程當中的Bug分析
基於對ajax技術理解,實現ajax方式的Get,Post,Put,Delete等請求的異步處理,如圖所示:
基於業務描述,在AjaxController類中添加相關屬性和方法,用於處理客戶端的ajax請求.
添加屬性和構造方法,代碼以下:
/**假設這個是用於存儲數據的數據庫*/ private List<Map<String,Object>> dbList=new ArrayList<>(); public AjaxController(){ Map<String,Object> map=new HashMap<>(); map.put("id","100"); map.put("name","家用電器"); map.put("parentId",null);//parentId爲null則表示它是1級分類 map.put("remark","電器相關等"); map.put("createdTime",new Date()); dbList.add(map); }
添加Ajax請求處理方法,代碼以下:
@GetMapping("/doAjaxGet") public List<Map<String,Object>> doAjaxGet(){ return dbList; } @PostMapping("/doAjaxPost") public String doAjaxPost(@RequestParam Map<String,Object> map){ map.put("createdTime",new Date()); dbList.add(map); return "save ok"; } @DeleteMapping("/doAjaxDelete") public String doAjaxDelete(String id){ //獲取迭代器對象,而後迭代list集合,找到id對應的元素,進行刪除操做 Iterator it=dbList.iterator(); while(it.hasNext()){ Map<String,Object> map=(Map<String,Object>)it.next(); if(map.get("id").equals(id)){ //dbList.remove(map);//這樣刪除會出現併發刪除異常 it.remove();//經過迭代器執行刪除操做 } } return "delete ok"; } @PutMapping("/doAjaxUpdate") public String doAjaxUpdate(@RequestParam Map<String,Object> updateMap){ Iterator it=dbList.iterator(); while(it.hasNext()){ Map<String,Object> map=(Map<String,Object>)it.next(); if(map.get("id").equals(updateMap.get("id"))){ map.put("name",updateMap.get("name")); map.put("remark",updateMap.get("remark")); } } return "update ok"; }
在static目錄下建立ajax-02.html文件,關鍵代碼以下:
<h1>The Ajax 02 Page</h1> <button onclick="doAjaxGet()">Do Ajax Get</button> <button onclick="doAjaxPost()">Do Ajax Post</button> <button onclick="doAjaxDelete()">Do Ajax Delete</button> <button onclick="doAjaxUpdate()">Do Ajax Update</button> <div id="result"></div>
客戶端JavaScript腳本設計,代碼以下:
function doAjaxGet(){ let xhr=new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ document.getElementById("result").innerHTML=xhr.responseText; } } } xhr.open("GET","http://localhost/doAjaxGet",true); xhr.send(null); }
function doAjaxPost(){ let xhr=new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ document.getElementById("result").innerHTML=xhr.responseText; } } } xhr.open("POST","http://localhost/doAjaxPost",true); //post請求向服務端傳遞數據,須要設置請求頭,必須在open以後 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //發送請求(post請求傳遞數據,須要將數據寫入到send方法內部) xhr.send("id=101&name=Computer&remark=Computer..."); }
function doAjaxUpdate(){ let xhr=new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ document.getElementById("result").innerHTML=xhr.responseText; } } } xhr.open("put","http://localhost/doAjaxUpdate",true); //post請求向服務端傳遞數據,須要設置請求頭,必須在open以後 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //發送請求(post請求傳遞數據,須要將數據寫入到send方法內部) xhr.send("id=101&name=Book&remark=Book..."); }
function doAjaxDelete(){ let xhr=new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ document.getElementById("result").innerHTML=xhr.responseText; } } } xhr.open("delete","http://localhost/doAjaxDelete?id=101",true); xhr.send(null); }
在實際編程過程當中咱們一般會封裝代碼共性,提取代碼特性.而後來提升代碼的可重用性.例如:
function ajaxGet(url,params,callback) { let xhr = new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ callback(xhr.responseText); } } } xhr.open("GET",params?url+"?"+params:url,true); xhr.send(null); }
function ajaxPost(url,params,callback) {//add let xhr = new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ callback(xhr.responseText); } } } xhr.open("POST",url,true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send(params); }
function ajaxPut(url,params,callback) {//update let xhr = new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ callback(xhr.responseText); } } } xhr.open("PUT",url,true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send(params); }
function ajaxDelete(url,params,callback) { let xhr = new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ callback(xhr.responseText); } } } xhr.open("delete",params?url+"?"+params:url,true); xhr.send(null); }
咱們在實際的js編程中常常會以面向對象的方式進行實現,例如ajaxGet函數,如何以對象方式進行調用呢?關鍵代碼分析以下:(以下代碼的理解須要具有JS中面向對象的基礎知識,假如不熟可暫時跳過)
(function(){ //定義一個函數,能夠將其鏈接爲java中的類 var ajax=function(){} //在變量ajax指向的類中添加成員,例如doAjaxGet函數,doAjaxPost函數 ajax.prototype={ ajaxGet:function(url,params,callback){ //建立XMLHttpRequest對象,基於此對象發送請求 var xhr=new XMLHttpRequest(); //設置狀態監聽(監聽客戶端與服務端通信的狀態) xhr.onreadystatechange=function(){//回調函數,事件處理函數 if(xhr.readyState==4&&xhr.status==200){ //console.log(xhr.responseText); callback(xhr.responseText);//jsonStr } }; //創建鏈接(請求方式爲Get,請求url,異步仍是同步-true表示異步) xhr.open("GET",url+"?"+params,true); //發送請求 xhr.send(null);//GET請求send方法不寫內容 }, ajaxPost:function(url,params,callback){ //建立XMLHttpRequest對象,基於此對象發送請求 var xhr=new XMLHttpRequest(); //設置狀態監聽(監聽客戶端與服務端通信的狀態) xhr.onreadystatechange=function(){//回調函數,事件處理函數 if(xhr.readyState==4&&xhr.status==200){ //console.log(xhr.responseText); callback(xhr.responseText);//jsonStr } }; //創建鏈接(請求方式爲POST,請求url,異步仍是同步-true表示異步) xhr.open("POST",url,true); //post請求傳參時必須設置此請求頭 xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //發送請求 xhr.send(params);//post請求send方法中傳遞參數 } } window.Ajax=new ajax();//構建ajax對象並賦值給變量全局變量Ajax })()
此時外界再調用doAjaxGet和doAjaxPost函數時,能夠直接經過Ajax對象進行實現。
jQuery是一個快速、簡潔的JavaScript庫框架,是一個優秀的JavaScript代碼庫(或JavaScript框架)。jQuery設計的宗旨是「write Less,Do More」,即倡導寫更少的代碼,作更多的事情。它封裝JavaScript經常使用的功能代碼,提供一種簡便的JavaScript設計模式,優化HTML文檔操做、事件處理、動畫設計和Ajax交互。
jQuery中基於標準的ajax api 提供了豐富的Ajax函數應用,基於這些函數能夠編寫少許代碼,即可以快速實現Ajax操做。經常使用函數有:
說明:jquery 中ajax相關函數的語法可參考官網(jquery.com).
參考官方案例....
本章主要介紹了Ajax是什麼、應用場景、客戶端與服務端的通信模型、ajax編程的基本步驟、封裝過程以及ajax技術在一些JS框架中的應用等,而且重點分析了在ajax編碼過程當中的一些調試技巧。