在互聯網高速發展的今天,傳統的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,String>> dbList=new ArrayList<>(); public AjaxController(){ Map<String,String> map=new HashMap<String,String>(); map.put("id","100"); map.put("city","beijing"); dbList.add(map); map=new HashMap<String,String>(); map.put("id","101"); map.put("city","shanghai"); dbList.add(map); }
添加Ajax請求處理方法,代碼以下:
@GetMapping(path={"/doAjaxGet/{city}","/doAjaxGet") public List<Map<String,String> doAjaxGet(@PathVariable(required=false) String city){ List<Map<String,String>> list=new ArrayList<>(); for(Map<String,String> map:dbList){ if(map.get("city").contains(city)){ list.add(map); } } return list; } @PostMapping("/doAjaxPost") public String doAjaxPost(@RequestParam Map<String,String> map){ dbList.add(map); return "save ok"; } @PostMapping("/doAjaxPostJson") public String doAjaxPost(@RequestBody Map<String,String> map){ dbList.add(map); return "save ok"; } @DeleteMapping("/doAjaxDelete/{id}") public String doDeleteObject(@PathVariable String id){ //基於迭代器執行刪除操做 Iterator<Map<String,String>> it=dbList.iterator(); while(it.hasNext()){ Map<String,String> map=it.next(); if(map.get("id").equals(id)){ it.remove();//基於迭代器執行刪除操做 } } return "delete ok"; } @PostMapping("/doAjaxPut") public String doAjaxPut(@RequestParam Map<String,String> paramMap){ for(Map<String,String> map:dbList){ if(map.get("id").equals(paramsMap.get("id"))){ map.put("city",paramMap.get("city")) } } return "update ok"; }
在static目錄下建立ajax-02.html文件,關鍵代碼以下:
<div> <h1>The Ajax 02 Page</h1> <button onclick="doAjaxGet()">Do Ajax Get</button> <button onclick="doAjaxPost()">Do Ajax Post</button> <button onclick="doAjaxPostJson()">Do Ajax Post Json</button> <button onclick="doAjaxDelete()">Do Ajax Delete</button> <button onclick="doAjaxPut()">Do Ajax Put</button> </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; } } } let params="" xhr.open("GET",`http://localhost/doAjaxGet/${params}`,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=102&city=shenzhen"); }
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/json"); //發送請求(post請求傳遞數據,須要將數據寫入到send方法內部) let params={id:103,city:"xiongan"}; let paramsStr=JSON.stringify(params); xhr.send(paramsStr); }
function doAjaxPut(){ 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/doAjaxPut",true); //post請求向服務端傳遞數據,須要設置請求頭,必須在open以後 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); //發送請求(post請求傳遞數據,須要將數據寫入到send方法內部) xhr.send("id=101&city=tianjin"); }
function doAjaxDelete(){ let xhr=new XMLHttpRequest(); xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ document.getElementById("result").innerHTML=xhr.responseText; } } } let params="102"; xhr.open("delete",`http://localhost/doAjaxDelete/${params}`,true); xhr.send(null); }
在實際編程過程當中咱們一般會封裝代碼共性,提取代碼特性.而後來提升代碼的可重用性.例如:
xhr對象的建立
function createXHR(callback){ //1.create XHR object let xhr=new XMLHttpRequest(); //2.set onreadystatechange xhr.onreadystatechange=function(){ if(xhr.readyState==4){ if(xhr.status==200){ callback(xhr.responseText); } } } return xhr; }
Get請求
function ajaxGet(url,params,callback){//封裝ajax get 請求模板代碼 //1.create xhr and set onreadystate change let xhr=createXHR(callback); //2.open connection xhr.open("GET",`${url}/${params}`,true); //3.send request xhr.send(); }
Post請求
function ajaxPost(url,params,callback){//封裝ajax get 請求模板代碼 //1.create xhr and set onreadystate change let xhr=createXHR(callback); //2.open connection xhr.open("POST",url,true); xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //3.send request xhr.send(params); }
post 請求,傳遞json數據
function ajaxPostJSON(url,params,callback){ //1.create xhr and set onreadystate change let xhr=createXHR(callback); //2.open connection xhr.open("POST",url,true); xhr.setRequestHeader("Content-Type","application/json"); //3.send request xhr.send(JSON.stringify(params));//將json對象轉換爲json格式字符串提交到服務端 }
Put請求
function ajaxPut(url,params,callback){//封裝ajax get 請求模板代碼 //1.create xhr and set onreadystate change let xhr=createXHR(callback); //2.open connection xhr.open("put",url,true); xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //3.send request xhr.send(params); }
delete請求
function ajaxDelete(url,params,callback){//封裝ajax get 請求模板代碼 //1.create xhr and set onreadystate change let xhr=createXHR(callback); //2.open connection xhr.open("delete",`${url}/${params}`,true); //3.send request xhr.send(); }
建立ajax-03.html頁面,在頁面中分別調用如上函數進行訪問測試,關鍵代碼以下:
<div> <h1>The Ajax 03 Page</h1> <button onclick="doAjaxGet()">Do Ajax Get</button> <button onclick="doAjaxPost()">Do Ajax Post</button> <button onclick="doAjaxPostJson()">Do Ajax Post Json</button> <button onclick="doAjaxDelete()">Do Ajax Delete</button> <button onclick="doAjaxPut()">Do Ajax Put</button> </div> <div id="result"></div> <script src="/js/ajax.js"></script> <script> //ajax delete request function doAjaxDelete(){ const url="/doAjaxDelete"; const params="101"; ajaxDelete(url,params,function(result){ alert(result); }) } //ajax post put function doAjaxPut(){ const url="/doAjaxPut"; const params="id=100&city=shenzhen"; ajaxPut(url,params,function(result){ alert(result); }) } //ajax post request function doAjaxPostJson(){ const url="/doAjaxPostJSON"; const params={id:"103",city:"xiongan"};//服務端須要@RequestBody ajaxPostJSON(url,params,function(result){ alert(result); }) } //ajax post request function doAjaxPost(){ const url="/doAjaxPost"; const params="id=102&city=shenzhen"; ajaxPost(url,params,function(result){ alert(result); }) } //ajax get request function doAjaxGet(){ const url="/doAjaxGet"; const params=""; ajaxGet(url,params,function(result){ document.querySelector("#result").innerHTML=result; }) } </script>
咱們在實際的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).
業務描述
構建一個html頁面,並經過一些button事件,演示jquery中相關ajax函數的基本應用,如圖所示:
關鍵步驟及代碼設計以下:
第一步:在static目錄下添加jquery-ajax-01.html頁面.
第二步:在頁面上添加關鍵的html元素,代碼以下:
<h1>The Jquery Ajax 01 Page</h1> <button onclick="doAjax()">$.ajax(...)</button> <button onclick="doAjaxPost()">$.post(...)</button> <button onclick="doAjaxGet()">$.get(...)</button> <button onclick="doAjaxLoad()">$("..").load(...)</button> <div id="result"></div> <script src="/js/jquery.min.js"></script>
第三步:添加button事件對應的事件處理函數,代碼以下:
function doAjax(){ let url="http://localhost/doAjaxGet"; let params=""; //這裏的$表明jquery對象 //ajax({})這是jquery對象中的一個ajax函數(封裝了ajax操做的基本步驟) $.ajax({ type:"GET",//省略type,默認就是get請求 url:url, data:params, async:true,//默認爲true,表示異步 success:function(result){//result爲服務端響應的結果 console.log(result);//ajax函數內部將服務端返回的json串轉換爲了js對象 }//success函數會在服務端響應狀態status==200,readyState==4的時候執行. }); }
function doAjaxPost(){ let url="http://localhost/doAjaxPost"; let params="id=101&name=Computer&remark=Computer..."; $.post(url,params,function(result){ $("#result").html(result); });
function doAjaxGet(){ let url="http://localhost/doAjaxGet"; let params=""; $.get(url,params,function(result){ $("#result").html(result); },"text"); }
function doAjaxLoad(){ let url="http://localhost/doAjaxGet"; $("#result").get(url,function(){ console.log("load complete") }); }
本章主要介紹了Ajax是什麼、應用場景、客戶端與服務端的通信模型、ajax編程的基本步驟、封裝過程以及ajax技術在一些JS框架中的應用等,而且重點分析了在ajax編碼過程當中的一些調試技巧。