Ajax异步(7)前端
1 Ajax概述
??AJAX 即“Asynchronous Javascript And XML”(異步 JavaScript和 XML),是指一種創建交互式、快速動態網頁應用的網頁開發技術,無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。通過在后臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。
- AJAX關鍵技術
(1)使用CSS構建用戶界面樣式,負責頁面排版和美工
(2)使用DOM進行動態顯示和交互,對頁面進行局部修改
(3)使用XMLHttpRequest異步獲取數據
(4)使用JavaScript將所有的元素綁定在一起 - 特點:異步訪問,局部刷新
2 同步和異步交互(前置知識)
2.1 什么是同步交互
??舉個同步的例子,用戶在使用瀏覽器訪問某個頁面的時候,首先用戶會向HTTP服務器提交一個處理請求。接著服務器端接收到請求后,按照預先編寫好的程序中的業務邏輯進行處理(比如和數據庫服務器進行數據信息交換)。最后,服務器對請求進行響應,將結果返回給客戶端,返回一個HTML等文件在瀏覽器中解析顯示。
??為什么說是同步呢?因為在服務器返回結果之前,用戶不能進行其他操作,必須要等到服務器返回了結果才能進行其他操作。這就是同步。
- 優點:
??可以保留瀏覽器后退按鈕的正常功能。在動態更新頁面的情況下,用戶可以回到前一個頁面狀態,瀏覽器能記下歷史記錄中的靜態頁面,用戶通常都希望單擊后退按鈕時,就能夠取消他們的前一次操作,同步交互可以實現這個需求. - 缺點:
(1)同步交互的不足之處,會給用戶一種不連貫的體驗,當服務器處理請求時,用戶只能等待狀態,頁面中的顯示內容只能是空白。
(2)因為已經跳轉到新的頁面,原本在頁面上的信息無法保存,好多信息需要重新填寫。
2.2 什么是異步交互
??指發送一個請求,不需要等待返回,隨時可以再發送下一個請求,即不需要等待。在部分情況下,我們的項目開發中都會優先選擇不需要等待的異步交互方式。將用戶請求放入消息隊列,并反饋給用戶,系統遷移程序已經啟動,你可以關閉瀏覽器了。然后程序再慢慢地去寫入數據庫去。這就是異步。異步不用等所有操作等做完,就響應用戶請求。即先響應用戶請求,然后慢慢去寫數據庫,用戶體驗較好。
- 優點:
(1)前端用戶操作和后臺服務器運算可以同時進行,可以充分利用用戶操作的間隔時間完成運算
(2)頁面沒有跳轉,響應回來的數據直接就在原頁面上,頁面原有信息得以保留 - 缺點:
??可能破壞瀏覽器后退按鈕的正常行為。在動態更新頁面的情況下,用戶無法回到前一個頁面狀態,這是因為瀏覽器僅能記錄的始終是當前一個的靜態頁面。用戶通常都希望單擊后退按鈕,就能夠取消他們的前一次操作,但是在AJAX這樣異步的程序,卻無法這樣做。
3 案例1:異步驗證用戶名是否被占用
案例內容:驗證用戶名是否被占用。JS表單驗證只能校驗格式是否正確,但是無法驗證用戶名是否已經存在,這個就需要后臺程序接受到數據后通過查詢才能夠完成的,那么這里就非常適用于使用異步方式校驗,保證用于數據提交后,業務完成的成功率,提升用于體驗感。
3.1 頁面代碼
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>$Title%sSourceCode%lt;</title><script>var xhr ;function checkUname(){// 獲取輸入框中的內容var unameDOM=document.getElementById("unameI");var unameText =unameDOM.value;var unameInfoDom =document.getElementById("unameInfo");if(null == unameText || unameText == ''){unameInfoDom.innerText="用戶名不能為空";return;}unameInfoDom.innerText="";// 發送異步請求// 獲取一個 XMLHttpRequest對象 ,對象可以幫助我們發送異步請求xhr =new XMLHttpRequest();// 使用xhr對象設置打開鏈接,設置請求方式和參數xhr.open("請求方式","請求的URL",是否使用異步方式);xhr.open("GET","unameCheckServlet.do?uname="+unameText,true);// 設置回調函數xhr.onreadystatechange=showReturnInfo;// 正式發送請求xhr.send(null);}function showReturnInfo(){if(xhr.readyState==4 && xhr.status==200){var returnInfo =xhr.responseText;var unameInfoDom =document.getElementById("unameInfo");unameInfoDom.innerText=returnInfo;}}</script> </head> <body> <form action="myServlet1.do" >用戶名:<input id="unameI" type="text" name="uname" onblur="checkUname()"><span id="unameInfo" style="color: red"></span><br/>密碼:<input type="password" name="pwd"><br/><input type="submit"> </form> </body> </html>3.2 servlet代碼
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@WebServlet("/unameCheckServlet.do") public class NameCheckServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uname = req.getParameter("uname");String info = "";if ("jayden".equals(uname)){info = "用戶名已被注冊";}else{info = "用戶名可以用";}//想瀏覽器返回結果resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");resp.getWriter().print(info);} }3.3 總結
- AJAX異步提交請求的步驟為
(1)獲取XMLHTTPRequest對象xhr=new XMLHttpRequest();
(2)打開鏈接xhr.open(“GET”,“loginServlet?uname=”+uname,true);
(3)設置回調函數xhr.onreadystatechange=showRnturnInfo;
(4)提交數據 xhr.send(data) - 目前存在的問題:
??原生js提交AJAX異步請求代碼比較繁瑣,處理復雜數據比較麻煩,后續可以使用jQuery解決
4 JSON格式
4.1 JSON介紹
??如果服務器給我們響應的數據非常簡答,那么直接使用字符串就好了。但是,AJAX異步返回的數據如果有很多,那么就不好處理了,所以我們使用一個名叫JSON的文件格式來封裝多個數據。
??JSON(JavaScript Object Notation, JS 對象簡譜) 是一種輕量級的數據交換格式。它基于ECMAScript (歐洲計算機協會制定的js規范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得JSON 成為理想的數據交換語言。 易于人閱讀和編寫,同時也易于機器解析和生成,并有效地提升網絡傳輸效率。
-
優點
(1)輕量級,在這里用它不是為了厲害的功能代碼,而是為了實現數據轉換
(2)Json 格式既能考慮到前端對象的特點 同時也能兼顧后臺對象信息的特點
(3)Json 格式可以被前端直接識別并解析成對象
(4)jQuery形式實現AJAX默認前后端傳遞數據的格式就是JSON
例子:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head><title>Title</title><script>/** JSON格式創建對象* {"屬性名":"屬性值","屬性名":屬性值 ... ... }* */var person ={"name":"zhangsan","age":10}alert(person.name)alert(person.age)var persons =[{"name":"zhangsan","age":10},{"name":"lisi","age":10},{"name":"wangwu","age":10}];for (var i = 0; i <persons.length ; i++) {var person =persons[i];console.log(person.name)console.log(person.age)}var personStr='{"name":"zhangsan","age":10}';// 是一個字符串// 可以直接把上面這種格式的字符串直接轉換成對象var p =JSON.parse(personStr);console.log(p.name)console.log(p.age)</script> </head> <body> </body> </html>4.2 JSON 與 JS 對象的關系
??很多人搞不清楚 JSON 和 JS 對象的關系,甚至連誰是誰都不清楚。其實,可以這么理解:JSON 是 JS 對象的字符串表示法,它使用文本表示一個 JS 對象的信息,本質是一個字符串。
var obj = {a: 'Hello', b: 'World'}; //這是一個對象,注意鍵名也是可以使用引號包裹的 var json = '{"a": "Hello", "b": "World"}'; //這是一個 JSON 字符串,本質是一個字符串4.3 JSON 和 JS 對象轉化方法
??要實現從JSON字符串轉換為JS對象,使用 JSON.parse() 方法:
var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //結果是 {a: 'Hello', b: 'World'}??要實現從JS對象轉換為JSON字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: 'Hello', b: 'World'}); //結果是 '{"a": "Hello", "b": "World"}'4.4 GSON工具類的使用
??JSON格式字符串,拼接比較麻煩,可以修改toString方法但是就破壞了toString原有的格式,而且一旦字段如果太多修改工作量大,所以后續可以使用JSON工具類來轉換。
??gson工具類中已經給我們封裝好了json格式和java對象之間轉換的API,我們直接使用即可,再也不用手動去轉換項目中。
- 需要添加gson-2.2.4.jar(在web項目的web目錄下,用一個自定義lib然后把包復制進去,然后右鍵加入到庫即可)
例子:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html><head><title>$Title%sSourceCode%lt;/title><script>var xhr ;function testData(){xhr =new XMLHttpRequest();xhr.open("GET","testServlet.do",true);xhr.onreadystatechange=showReturnInfo;xhr.send(null);}function showReturnInfo(){if(xhr.readyState==4 && xhr.status==200){var info =xhr.responseText;var users=JSON.parse(info)for (var i = 0; i <users.length ; i++) {var user =users[i];console.log(user.uname)console.log(user.age)console.log(user.gender)console.log(user.birthday)}}}</script></head><body><input type="button" value="測試" onclick="testData()"></body> </html>后臺代碼:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.msb.pojo.User; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Date; /*** @Author: Ma HaiYang* @Description: MircoMessage:Mark_7001*/ @WebServlet("/testServlet.do") public class TestServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {User user1 =new User("jayden",11,"男",new Date());User user2 =new User("11",12,"男",new Date());User user3 =new User("kim",22,"男",new Date());User user4 =new User("曉明4",125,"男",new Date());User user5 =new User("曉明5",10,"男",new Date());ArrayList<User> list =new ArrayList<>();Collections.addAll(list,user1,user2,user3,user4,user5);// 響應普通文本數據resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");GsonBuilder gsonBuilder = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss");Gson gson = gsonBuilder.create();String str = gson.toJson(list);System.out.println(str);resp.getWriter().print(str);} }5 AJAX結合JQuery實現
5.1 JQuery.ajax()的簡單使用
??每次書寫AJAX代碼比較繁瑣,步驟都是一樣的,數據回顯使用原生js代碼也比較繁瑣,所以可以使用jQuery對上述問題進行優化,jQuery不僅僅對dom操作進行了封裝,同時也對AJAX提交和回顯已經進行了封裝,可大大簡化AJAX的操作步驟。
- 案例1:
(1)首先創建一個javaWeb項目,然后將需要的JQuery包導入進去。(注意:一定要放在web目錄包下,這樣編譯時才能把這個包集成到服務器項目中,另外服務器端的包要放在web目錄的WEB-INF目錄下。)
(2)編寫html代碼
(3)后端Servlet代碼
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;/*** @Auther: jayden* @Date: 2022-05-05 - 05 - 05 - 9:11* @Description: demo* @version: 1.0*/ @WebServlet("/nameCheckServlet.do") public class nameCheckServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uname = req.getParameter("name");String info="";if("jayden".equals(uname)){info="用戶名已經占用";}else{info="用戶名可用";}// 向瀏覽器響應數據resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");resp.getWriter().print(info);} }- 案例2
(1)導包。(注意:一定要放在web目錄包下,這樣編譯時才能把這個包集成到服務器項目中,另外服務器端的包要放在web目錄的WEB-INF目錄下。)
(2)編寫html前端代碼
(3)編寫Servlet后端代碼
import com.google.gson.Gson; import com.google.gson.GsonBuilder;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Date;/*** @Auther: jayden* @Date: 2022-05-05 - 05 - 05 - 9:19* @Description: demo* @version: 1.0*/ @WebServlet("/jsonServlet.do") public class JsonServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);System.out.println(password);Student stu1=new Student("小黑","男",10,new Date());Student stu2=new Student("小白","男",10,new Date());Student stu3=new Student("小黃","男",10,new Date());Student stu4=new Student("小花","男",10,new Date());ArrayList<Student> list =new ArrayList<>();Collections.addAll(list,stu1,stu2,stu3,stu4);GsonBuilder gb =new GsonBuilder();gb.setDateFormat("yyyy-MM-dd");Gson gson = gb.create();String json = gson.toJson(list);resp.setContentType("text/html;charset=UTF-8");resp.setCharacterEncoding("UTF-8");resp.getWriter().print(json);} }5.2 JQuery.ajax()屬性介紹
??$.ajax()方法中有很多屬性可以供我們使用,其中很多屬性都有默認值,那么這些屬性都有哪些,處理的是什么事情?接下來給大家一一介紹一下
1.url:
??要求為String類型的參數,(默認為當前頁地址)發送請求的地址。
2.type:
??要求為String類型的參數,請求方式(post或get)默認為get。注意其他http請求方法,例如put和delete也可以使用,但僅部分瀏覽器支持。
3.timeout:
??要求為Number類型的參數,設置請求超時時間(毫秒)。此設置將覆蓋$.ajaxSetup()方法的全局設置。
4.async:
??要求為Boolean類型的參數,默認設置為true,所有請求均為異步請求。如果需要發送同步請求,請將此選項設置為false。注意,同步請求將鎖住瀏覽器,用戶其他操作必須等待請求完成才可以執行。
5.cache:
??要求為Boolean類型的參數,默認為true(當dataType為script時,默認為false),設置為false將不會從瀏覽器緩存中加載請求信息。
6.data:
??要求為Object或String類型的參數,發送到服務器的數據。如果已經不是字符串,將自動轉換為字符串格式。get請求中將附加在url后。防止這種自動轉換,可以查看 processData選項。對象必須為key/value格式,例如{foo1:“bar1”,foo2:“bar2”}轉換為&foo1=bar1&foo2=bar2。如果是數組,JQuery將自動為不同值對應同一個名稱。例如{foo:[“bar1”,“bar2”]}轉換為&foo=bar1&foo=bar2。
7.dataType:
??要求為String類型的參數,預期服務器返回的數據類型。如果不指定,JQuery將自動根據http包mime信息返回responseXML或responseText,并作為回調函數參數傳遞。可用的類型如下:
xml:返回XML文檔,可用JQuery處理。
html:返回純文本HTML信息;包含的script標簽會在插入DOM時執行。
script:返回純文本JavaScript代碼。不會自動緩存結果。除非設置了cache參數。注意在遠程請求時(不在同一個域下),所有post請求都將轉為get請求。
json:返回JSON數據。
jsonp:JSONP格式。使用JSONP形式調用函數時,例如myurl?callback=?,JQuery將自動替換后一個“?”為正確的函數名,以執行回調函數。
text:返回純文本字符串。
8.beforeSend:
??要求為Function類型的參數,發送請求前可以修改XMLHttpRequest對象的函數,例如添加自定義HTTP頭。在beforeSend中如果返回false可以取消本次ajax請求。
XMLHttpRequest對象是惟一的參數。
function(XMLHttpRequest){
this; //調用本次ajax請求時傳遞的options參數
}
9.complete:
??要求為Function類型的參數,請求完成后調用的回調函數(請求成功或失敗時均調用)。參數:XMLHttpRequest對象和一個描述成功請求類型的字符串。
function(XMLHttpRequest, textStatus){
this; //調用本次ajax請求時傳遞的options參數
}
10.success:
??要求為Function類型的參數,請求成功后調用的回調函數,有兩個參數。
(1)由服務器返回,并根據dataType參數進行處理后的數據。
(2)描述狀態的字符串。
function(data, textStatus){
//data可能是xmlDoc、jsonObj、html、text等等
this; //調用本次ajax請求時傳遞的options參數
}
11.error:
??要求為Function類型的參數,請求失敗時被調用的函數。該函數有3個參數,即XMLHttpRequest對象、錯誤信息、捕獲的錯誤對象(可選)。ajax事件函數如下:
function(XMLHttpRequest, textStatus, errorThrown){
//通常情況下textStatus和errorThrown只有其中一個包含信息
this; //調用本次ajax請求時傳遞的options參數
}
12.contentType:
??要求為String類型的參數,當發送信息至服務器時,內容編碼類型默認為"application/x-www-form-urlencoded"。該默認值適合大多數應用場合。
13.dataFilter:
??要求為Function類型的參數,給Ajax返回的原始數據進行預處理的函數。提供data和type兩個參數。data是Ajax返回的原始數據,type是調用jQuery.ajax時提供的dataType參數。函數返回的值將由jQuery進一步處理。
function(data, type){
//返回處理后的數據
return data;
}
14.global:
??要求為Boolean類型的參數,默認為true。表示是否觸發全局ajax事件。設置為false將不會觸發全局ajax事件,ajaxStart或ajaxStop可用于控制各種ajax事件。
15.ifModified:
??要求為Boolean類型的參數,默認為false。僅在服務器數據改變時獲取新數據。服務器數據改變判斷的依據是Last-Modified頭信息。默認值是false,即忽略頭信息。
16.jsonp:
??要求為String類型的參數,在一個jsonp請求中重寫回調函數的名字。該值用來替代在"callback=?"這種GET或POST請求中URL參數里的"callback"部分,例如{jsonp:‘onJsonPLoad’}會導致將"onJsonPLoad=?"傳給服務器。
17.username:
??要求為String類型的參數,用于響應HTTP訪問認證請求的用戶名。
18.password:
??要求為String類型的參數,用于響應HTTP訪問認證請求的密碼。
19.processData:
??要求為Boolean類型的參數,默認為true。默認情況下,發送的數據將被轉換為對象(從技術角度來講并非字符串)以配合默認內容類型"application/x-www-form-urlencoded"。如果要發送DOM樹信息或者其他不希望轉換的信息,請設置為false。
20.scriptCharset:
??要求為String類型的參數,只有當請求時dataType為"jsonp"或者"script",并且type是GET時才會用于強制修改字符集(charset)。通常在本地和遠程的內容編碼不同時使用。
一個ajax方法中,可用的屬性和方法大致如下
<script>function testAjax(){$.ajax({url:"servlet1",/*post get 部分瀏覽器可使用put delete*/type:"get",/*請求超時的時間設置*/timeout:2000,/*是否發送異步請求,默認值為true,如需同步請求,改為false*/async:true,/*是否從瀏覽器的緩存中加載信息,默認為true,false則不讀取瀏覽器緩存*/cache:true,/*向服務器發送的數據,可以是key/value格式,也可以是對象格式* get方式下,會將信息附加在url后,如果數據不是字符串,會轉換成字符串格式* */data:{username:"bjmsb",password:"bjmsb"},/** 默認值為true 默認情況下,發送的數據將被轉換為對象以配合* content-type:application/x-www-form-urlencoded* 如果發送信息不希望被轉換,設置為false即可* */proccessData:true,/*發送到服務器的數據為String類型時,默認值為* application/x-www-form-urlencoded* 該值適合大多數應用場景* */contentType:"application/x-www-form-urlencoded",/** 預期服務器返回值類型,* 如果不指定 jQuery根據http響應mime信息返回xml或者text* 并作為返回值傳遞,可選類型如下* xml 返回xml數據(基本淘汰)* html:返回純文本HTML信息* script:返回JS腳本,* json:返回json數據* jsonp:jsonp格式* text:返回純文本,也是默認格式* */dataType:"json",/** 指定跨域回調函數名* *///jsonp:"fun1",/*只有當請求參數為dataType為jsonp或者script,并且是get方式請求時* 才能強制修改字符集,通常在跨域編碼不同時使用* */// scriptCharset:"utf-8",beforeSend:function(XMLHttpRequest){/** 請求發送前可以通過該方法修改XMLHttpRequest對象函數* 如聽見請求頭* 如果該方法返回false,則會取消ajax請求* */},success:function(data,textStatus){/**一般請求成功后會調用的函數,有兩個可選參數* data,數據 根據dataType的配置處理之后的數據 可能是xml text json 等* testStatus ,描述響應狀態的字符串* */},error:function(XMLHttpRequest,textStatus,errorThrown){/** 請求失敗時調用的函數,可選參數有* XMLHttpRequest對象* 錯誤信息* 捕獲的異常對象* */},complete:function(XMLHttpRequest,textStatus){/** 無論請求是否成功都睡調用的回調函數* 可選參數有* XMLHttpRequest對象* textStatus 描述成功請求的類型的字符串* */},dataFilter:function(data,type){/** 數據過濾方法* 給Ajax返回的原始數據進行預處理的函數。* 提供data和type兩個參數。* data是Ajax返回的原始數據,* type是調用jQuery.ajax時提供的dataType參數。* 函數返回的值將由jQuery進一步處理* */}})}</script>注意:
??ajax異步提交的可選屬性和方法較多,實際研發我們沒必要寫這么多,一般可以使用默認值的屬性就可以省略不寫,一些業務邏輯或者功能上不需要的方法也可以省略不寫,由于屬性太多,針對于一些特殊情況,jQuery也給我們提供了一些專用的方法,這樣可以簡化$.ajax的寫法,每一種簡化寫法都相當于已經指定了$.ajax一些屬性的值.
5.3 JQuery實現ajax的其他寫法
1.$.load()
??jQuery load() 方法是簡單但強大的 AJAX 方法,load() 方法從服務器加載數據,并把返回的數據放入被選元素中。默認使用 GET 方式 - 傳遞附加參數時自動轉換為 POST 方式,
語法為:$(selector).load(URL,data,callback);
參數的含義為:
url: URL地址
data:待發送參數。
callback:載入成功時回調函數。
案例:(準備兩個HTML頁面和一個Servlet)
??這是一個簡單的 GET 請求功能以取代復雜 $.ajax 。請求成功時可調用回調函數。如果需要在出錯時執行函數,請使用$.ajax。
語法為:$.get(url,[data],[callback],[type])
參數的含義為:
url: URL地址
data:待發送參數。
callback:載入成功時回調函數。
type:返回內容格式,xml, html, script, json, text, _default
該函數是簡寫的 Ajax 函數,等價于:
$.ajax({type: 'GET',url: url,data: data,success: success,dataType: dataType });??JSON是一種較為理想的數據傳輸格式,它能夠很好的融合與JavaScript或其他宿主語言,并且可以被JS直接使用。使用JSON相比傳統的通過 GET、POST直接發送“裸體”數據,在結構上更為合理,也更為安全。至于jQuery的getJSON()函數,只是設置了JSON參數的ajax()函數的一個簡化版本。
語法為:
該函數是簡寫的 Ajax 函數,等價于:
$.ajax({url: url,data: data,success: callback,dataType: json });僅僅是等效于上述函數,但是除此之外這個函數也是可以跨域使用的,相比get()、post()有一定優勢。另外這個函數可以通過把請求url寫 成"myurl?callback=X"這種格式,讓程序執行回調函數X。
4.$.post()
注意:$.getJSON是以GET方式提交數據,如果需要提交很大的數據量,可選$.post。
這是一個簡單的 POST 請求功能以取代復雜 $.ajax 。請求成功時可調用回調函數。如果需要在出錯時執行函數,請使用$.ajax。
語法為:$.post(url,[data],[callback],[type])
參數的含義為:
url: URL地址
data:待發送參數。
callback:載入成功時回調函數。
type:返回內容格式,xml, html, script, json, text, _default
該函數是簡寫的 Ajax 函數,等價于:
$.ajax({type: 'POST',url: url,data: data,success: success,dataType: dataType });案例:
<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><script src="js/jquery.min.js"></script><script>function testAjax(){$.get("servlet1.do",{"username":"zhangsan","password":"123456"},function(list){$.each(list,function(i,e){console.log(e)})},"json")console.log("------------------------------")$.getJSON("servlet1.do",{"username":"zhangsan","password":"123456"},function(list){$.each(list,function(i,e){console.log(e)})})console.log("------------------------------")$.post("servlet1.do",{"username":"zhangsan","password":"123456"},function(list){$.each(list,function(i,e){console.log(e)})},"json")}</script> </head> <body> <input type="button" value="測試" onclick="testAjax()"> </body> </html> import com.google.gson.Gson; import com.google.gson.GsonBuilder;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Date;/*** @Auther: jayden* @Date: 2022-05-05 - 05 - 05 - 10:42* @Description: demo* @version: 1.0*/ @WebServlet("/servlet1.do") public class Servlet3 extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String username = req.getParameter("username");String password = req.getParameter("password");System.out.println(username);System.out.println(password);Student stu1=new Student("小黑","男",10,new Date());Student stu2=new Student("小白","男",10,new Date());Student stu3=new Student("小黃","男",10,new Date());Student stu4=new Student("小花","男",10,new Date());ArrayList<Student> list =new ArrayList<>();Collections.addAll(list,stu1,stu2,stu3,stu4);GsonBuilder gb =new GsonBuilder();gb.setDateFormat("yyyy-MM-dd");Gson gson = gb.create();String json = gson.toJson(list);resp.setContentType("text/html;charset=UTF-8");resp.setCharacterEncoding("UTF-8");resp.getWriter().print(json);} }5.4 jsonp跨域處理
-
什么是跨域?
??跨域問題是出于瀏覽器的同源策略限制。同源策略(Sameoriginpolicy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響。可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。同源策略會阻止一個域的javascript腳本和另外一個域的內容進行交互。所謂同源(即指在同一個域)就是兩個頁面具有相同的協議(protocol),主機(host)和端口號(port)。
以下是不同源的一些例子:
本地路徑地址:http://127.0.0.1:8080/msb/index.jsp
https://127.0.0.1:8080/msb/index.jsp 協議不一樣
http://192.168.24.11:8080/msb/index.jsp IP不一致
http://127.0.0.1:8888/msb/index.jsp 端口不一致
http://localhost:8080/msb/index.jsp IP不一致 -
實現跨域的原理是什么?
??我們發現Web頁面上調用js文件時則不受是否跨域的影響,擁有”src”這個屬性的標簽都卻擁有跨域的能力,比如<\script>、<\img>、<\iframe>。那么跨域訪問數據就有了一種可能,那就是在遠程服務器上設法把數據裝進js格式的文件里,供客戶端調用和進一步處理。就好比使用一個<script>,讓其src屬性指向我們要訪問的跨域資源,然后以接收js文件的形式接收數據。 -
通過:dataType:'jsonp'屬性實現跨域請求。
-
通過 jsonp:'callback'屬性簡化回調函數處理。
??通過 jsonp:’callback’,實現自動處理回調函數名,相當于在url地址欄最后后拼接一個callback=函數名,后臺自動根據這個函數名處理JS腳本,jQuery也會根據這函數名自動在前端處理回調函數,這樣我們直接在success方法中接收返回的數據即可,可以不用自己去自己定義回調函數.后臺獲取參數時,參數名要要和jsonp:后面的函數名保持一致。 -
案例:
(1)HTML代碼
(2)Servlet后端代碼
import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException;@WebServlet("/unameCheckServlet.do") public class UnameCheckServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String uname = req.getParameter("uname");String callBack = req.getParameter("aaa");System.out.println(uname);String info="";if("jayden".equals(uname)){info="用戶名已經占用";}else{info="用戶名可用";}// 向瀏覽器響應數據resp.setCharacterEncoding("UTF-8");resp.setContentType("text/javaScript;charset=UTF-8");resp.getWriter().print(callBack+"('"+info+"')");} }- 通過getJson方實現跨域請求
??getJSON方法是可以實現跨域請求的,在用該方法實現跨域請求時,在傳遞參數上應該注意在url后拼接一個jsoncallback=?,jQuery會自動替換?為正確的回調函數名,我們就可以不用單獨定義回調函數了
- 通過后臺代碼也可以實現跨域,一般在過濾器中添加如下代碼,那么前端在請求時就不用考慮跨域問題了
6 案例2:三級聯動
- 效果:
- 創建一個web項目,項目結構如下
- 各個類的代碼
(1)JSP代碼
(2)Controller代碼
package com.jayden.controller;import com.google.gson.Gson; import com.jayden.pojo.Area; import com.jayden.service.AreaService; import com.jayden.service.impl.AreaServiceImpl;import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List;@WebServlet("/areaController.do") public class AreaController extends HttpServlet {private AreaService areaService = new AreaServiceImpl();@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Integer parentID=0;try {parentID= Integer.parseInt(req.getParameter("parentID"));} catch (NumberFormatException e) {e.printStackTrace();}List<Area> areas=areaService.findByParentID(parentID);String json = new Gson().toJson(areas);resp.setCharacterEncoding("UTF-8");resp.setContentType("text/html;charset=UTF-8");resp.getWriter().print(json);} }(3)Service代碼
package com.jayden.service.impl;import com.jayden.dao.AreaDao; import com.jayden.dao.impl.AreaDaoImpl; import com.jayden.pojo.Area; import com.jayden.service.AreaService;import java.util.List;public class AreaServiceImpl implements AreaService {private AreaDao areaDao =new AreaDaoImpl();@Overridepublic List<Area> findByParentID(Integer parentID) {List<Area> areas = areaDao.findByParentID(parentID);return areas;} }(4)Dao層代碼
package com.jayden.dao.impl;import com.jayden.dao.AreaDao; import com.jayden.dao.BaseDao; import com.jayden.pojo.Area;import java.util.List;public class AreaDaoImpl extends BaseDao implements AreaDao {@Overridepublic List<Area> findByParentID(int parentID) {String sql="select * from area where parentid= ?";return baseQuery(Area.class, sql, parentID);} }(5)輔助類代碼
BaseDao
MyConnectionPool
package com.jayden.dao;import com.jayden.util.PropertiesUtil; import org.apache.log4j.Logger;import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.LinkedList;public class MyConnectionPool {private static String driver;private static String url;private static String user;private static String password;private static int initSize;private static int maxSize;private static Logger logger;private static LinkedList<Connection> pool;static{logger=Logger.getLogger(MyConnectionPool.class);// 初始化參數PropertiesUtil propertiesUtil=new PropertiesUtil("/jdbc.properties");driver=propertiesUtil.getProperties("driver");url=propertiesUtil.getProperties("url");user=propertiesUtil.getProperties("user");password=propertiesUtil.getProperties("password");initSize=Integer.parseInt(propertiesUtil.getProperties("initSize"));maxSize=Integer.parseInt(propertiesUtil.getProperties("maxSize"));// 加載驅動try {Class.forName(driver);} catch (ClassNotFoundException e) {logger.fatal("找不到數據庫驅動類"+driver,e);}// 初始化poolpool=new LinkedList<Connection>();// 創建5個鏈接對象for (int i = 0; i <initSize ; i++) {Connection connection = initConnection();if(null != connection){pool.add(connection);logger.info("初始化連接"+connection.hashCode()+"放入連接池");}}}// 私有的初始化一個鏈接對象的方法private static Connection initConnection(){try {return DriverManager.getConnection(url,user,password);} catch (SQLException e) {logger.fatal("初始化連接異常",e);}return null;}// 共有的向外界提供鏈接對象的public static Connection getConnection(){Connection connection =null;if(pool.size()>0){connection= pool.removeFirst();// 移除集合中的第一個元素logger.info("連接池中還有連接:"+connection.hashCode());}else{connection = initConnection();logger.info("連接池空,創建新連接:"+connection.hashCode());}return connection;}// 共有的向連接池歸還連接對象的方法public static void returnConnection(Connection connection){if(null != connection){try {if(!connection.isClosed()){if(pool.size()<maxSize){try {connection.setAutoCommit(true);// 調整事務狀態logger.debug("設置連接:"+connection.hashCode()+"自動提交為true");} catch (SQLException e) {e.printStackTrace();}pool.addLast(connection);logger.info("連接池未滿,歸還連接:"+connection.hashCode());}else{try {connection.close();logger.info("連接池滿了,關閉連接:"+connection.hashCode());} catch (SQLException e) {e.printStackTrace();}}}else{logger.info("連接:"+connection.hashCode()+"已經關閉,無需歸還");}} catch (SQLException e) {e.printStackTrace();}}else{logger.warn("傳入的連接為null,不可歸還");}}}PropertiesUtil
package com.jayden.util;import java.io.IOException; import java.io.InputStream; import java.util.Properties;public class PropertiesUtil {private Properties properties;public PropertiesUtil(String path){properties=new Properties();InputStream inputStream = this.getClass().getResourceAsStream(path);try {properties.load(inputStream);} catch (IOException e) {e.printStackTrace();}}public String getProperties(String key){return properties.getProperty(key);}}(6)pojo類
package com.jayden.pojo; import java.io.Serializable;public class Area implements Serializable {private Integer areaid;private String areaname;private Integer parentid;private Integer arealevel;private Integer status;public Integer getAreaid() {return areaid;}public void setAreaid(Integer areaid) {this.areaid = areaid;}public String getAreaname() {return areaname;}public void setAreaname(String areaname) {this.areaname = areaname;}public Integer getParentid() {return parentid;}public void setParentid(Integer parentid) {this.parentid = parentid;}public Integer getArealevel() {return arealevel;}public void setArealevel(Integer arealevel) {this.arealevel = arealevel;}public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}public Area() {}public Area(Integer areaid, String areaname, Integer parentid, Integer arealevel, Integer status) {this.areaid = areaid;this.areaname = areaname;this.parentid = parentid;this.arealevel = arealevel;this.status = status;} }(7)配置類XML
jdbc.properties
log4j.properties
log4j.rootLogger=debug,stdoutlog4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.err log4j.appender.stdout.layout=org.apache.log4j.SimpleLayoutlog4j.appender.logfile=org.apache.log4j.FileAppender log4j.appender.logfile.File=d:/msb.log log4j.appender.logfile.layout=org.apache.log4j.PatternLayout log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %F %p %m%n總結
以上是生活随笔為你收集整理的Ajax异步(7)前端的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHS-P1酸度计
- 下一篇: android 编译器indel,Ove