谈谈Ajax(二)
昨天還沒有談完,今天做一個了解。
首先還是以錯誤,來講述。
?
一、AJax常見錯誤
Ajax常見的錯誤,除了昨天列舉的之外。還有就是如下狀態碼:
405,請求類型錯誤,比如請求是POST,你卻用GET,通常出現這種情況是在SpringMVC中的@RequestMapping,有使用SpringMVC經驗的小伙伴們都知道,@RequestMapping默認的請求方式為GET。如果你因為復制粘貼沒有仔細檢查,在調試Ajax的時候就會出現405狀態碼。當然了,你沒有通過Ajax的調試方式,通常就會直接走error,并不會出現405狀態碼的提示。一般情況下,出現這種問題的概率非常少,因為還有postman。通過postman進行接口測試,一般情況下,如果你的情況不對,直接提示不支持該請求。
?
415,服務器無法處理請求附帶的媒體格式。因為你在Ajax中加入了contentType并指定了媒體格式為application/json;
如果你的參數列表中沒有加入@RequestBody就會出現415。
@RequestBody通常用來處理contentType不是默認的application/x-www-form-urlcode編碼的內容。比如說application/json和application/xml,一般情況下處理application/json。
例如:
403,這個通常就是你的請求參數與接收參數不一致,比如createDate在前臺是String類型,但是后臺你卻用Date類型接收,就會出現這種問題。
一般情況下,當參數比較多的時候,建議使用對象(參數三個以上,就建議使用對象比較好)。
?
500,這個通常就是服務端代碼有問題了。這個就要根據具體的調試情況來看了。比如空指針或者是類型轉換異常等等。
?
二、如何調試Ajax
比如我通過postman來測試,沒有發現問題,并不代表web端異步請求沒有問題。比如我在上面說到的Ajax常見錯誤,這些常見錯誤,很少能通過postman來發現的。因為開發人員,會因為疏忽大意,懶得測試(單元測試)等可能的意外原因導致問題的出現。又或者是我通過單元測試發現沒問題,并不代表web開發請求url或者是安卓那邊請求沒問題。
比如:
?
這段代碼正常返回的集合數據是不帶斜杠的,而web請求卻帶斜杠。
這是因為String的原因,如果將其返回值換為Object或者并將其toJSONString()改為toJSON()就可以得到正常的json數據而不是帶斜杠的字符串數據。
雖然說,帶斜杠可以通過jQuery的eval、安卓那邊的replace方法解決,但是最好還是不要繞一大圈。
調式的手段,主要是在error的function加上對應的三個參數XMLHttpRequest、textStatus、errorThrown等。
彈出狀態碼的是XMLHttpRequest.status,正常的狀態碼應為200。
?
狀態碼詳解如下:
1**:請求收到,繼續處理
2**:操作成功收到,分析、接受
3**:完成此請求必須進一步處理
4**:請求包含一個錯誤語法或不能完成
5**:服務器執行一個完全有效請求失敗
100——客戶必須繼續發出請求
101——客戶要求服務器根據請求轉換HTTP協議版本
200——交易成功
201——提示知道新文件的URL
202——接受和處理、但處理未完成
203——返回信息不確定或不完整
204——請求收到,但返回信息為空
205——服務器完成了請求,用戶代理必須復位當前已經瀏覽過的文件
206——服務器已經完成了部分用戶的GET請求
300——請求的資源可在多處得到
301——刪除請求數據
302——在其他地址發現了請求數據
303——建議客戶訪問其他URL或訪問方式
304——客戶端已經執行了GET,但文件未變化
305——請求的資源必須從服務器指定的地址得到
306——前一版本HTTP中使用的代碼,現行版本中不再使用
307——申明請求的資源臨時性刪除
400——錯誤請求,如語法錯誤
401——請求授權失敗
402——保留有效ChargeTo頭響應
403——請求不允許
404——沒有發現文件、查詢或URl
405——用戶在Request-Line字段定義的方法不允許
406——根據用戶發送的Accept拖,請求資源不可訪問
407——類似401,用戶必須首先在代理服務器上得到授權
408——客戶端沒有在用戶指定的餓時間內完成請求
409——對當前資源狀態,請求不能完成
410——服務器上不再有此資源且無進一步的參考地址
411——服務器拒絕用戶定義的Content-Length屬性請求
412——一個或多個請求頭字段在當前請求中錯誤
413——請求的資源大于服務器允許的大小
414——請求的資源URL長于服務器允許的長度
415——請求資源不支持請求項目格式
416——請求中包含Range請求頭字段,在當前請求資源范圍內沒有range指示值,請求也不包含If-Range請求頭字段
417——服務器不滿足請求Expect頭字段指定的期望值,如果是代理服務器,可能是下一級服務器不能滿足請求
500——服務器產生內部錯誤
501——服務器不支持請求的函數
502——服務器暫時不可用,有時是為了防止發生系統過載
503——服務器過載或暫停維修
504——關口過載,服務器使用另一個關口或服務來響應用戶,等待時間設定值較長
505——服務器不支持或拒絕支請求頭中指定的HTTP版本
?
至于XMLHttpRequest.readyState說的是AJax異步請求服務器的過程(一共五個過程):
?
(0)未初始化
此階段確認XMLHttpRequest對象是否創建,并為調用open()方法進行未初始化作好準備。值為0表示對象已經存在,否則瀏覽器會報錯--對象不存在。
(1)載入
此階段對XMLHttpRequest對象進行初始化,即調用open()方法,根據參數(method,url,true)完成對象狀態的設置。并調用send()方法開始向服務端發送請求。值為1表示正在向服務端發送請求。
(2)載入完成
此階段接收服務器端的響應數據。但獲得的還只是服務端響應的原始數據,并不能直接在客戶端使用。值為2表示已經接收完全部響應數據。并為下一階段對數據解析作好準備。
(3)交互
此階段解析接收到的服務器端響應數據。即根據服務器端響應頭部返回的MIME類型把數據轉換成能通過responseBody、responseText或responseXML屬性存取的格式,為在客戶端調用作好準備。狀態3表示正在解析數據。
(4)完成
此階段確認全部數據都已經解析為客戶端可用的格式,解析已經完成。值為4表示數據解析完畢,可以通過XMLHttpRequest對象的相應屬性取得數據。
概而括之,整個XMLHttpRequest對象的生命周期應該包含如下階段:
創建-初始化請求-發送請求-接收數據-解析數據-完成
?
?
用個例子說明:
比如我給遠方的一個朋友打電話,
第一,我必須要有手機,沒有手機怎么打電話,對應(0);
第二,我要將我說的第一句話傳達給他,這是(1);
第三,我說的話已經傳達給他了,這是(2);
第四,他需要理解我話中所表達的意思是什么,這是(3);
第五,他已經理解的我話的意思,這是(4);
?
也許這個例子表達的不是特別恰當,但是我覺得已經可以比較好的說明異步請求服務的過程和readyState的含義。
?
?
三、Ajax中的參數含義(以jQuery中的$.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,并作為回調函數參數傳遞??捎玫念愋腿缦?#xff1a;
xml:返回XML文檔,可用JQuery處理。
html:返回純文本HTML信息;包含的script標簽會在插入DOM時執行。
script:返回純文本JavaScript代碼。不會自動緩存結果。除非設置了cache參數。注意在遠程請求時(不在同一個域下),所有post請求都將轉為get請求。
json:返回JSON數據。
jsonp:JSONP格式。使用SONP形式調用函數時,例如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.dataFilter:
要求為Function類型的參數,給Ajax返回的原始數據進行預處理的函數。提供data和type兩個參數。data是Ajax返回的原始數據,type是調用jQuery.ajax時提供的dataType參數。函數返回的值將由jQuery進一步處理。
??????????? function(data, type){
??????????????? //返回處理后的數據
??????????????? return data;
??????????? }
15.global:
要求為Boolean類型的參數,默認為true。表示是否觸發全局ajax事件。設置為false將不會觸發全局ajax事件,ajaxStart或ajaxStop可用于控制各種ajax事件。
16.ifModified:
要求為Boolean類型的參數,默認為false。僅在服務器數據改變時獲取新數據。服務器數據改變判斷的依據是Last-Modified頭信息。默認值是false,即忽略頭信息。
17.jsonp:
要求為String類型的參數,在一個jsonp請求中重寫回調函數的名字。該值用來替代在"callback=?"這種GET或POST請求中URL參數里的"callback"部分,例如{jsonp:'onJsonPLoad'}會導致將"onJsonPLoad=?"傳給服務器。
18.processData:
要求為Boolean類型的參數,默認為true。默認情況下,發送的數據將被轉換為對象(從技術角度來講并非字符串)以配合默認內容類型"application/x-www-form-urlencoded"。如果要發送DOM樹信息或者其他不希望轉換的信息,請設置為false。
19.scriptCharset:
要求為String類型的參數,只有當請求時dataType為"jsonp"或者"script",并且type是GET時才會用于強制修改字符集(charset)。通常在本地和遠程的內容編碼不同時使用。
上述的1,2,6,7,10,11,12是我開發過程中比較常用的。其他的幾乎很少用。
?
四、SSM框架與Ajax三種方式(主要說明參數傳遞和接收)
第一種,直接在參數列表中寫。
?
優點,直接指明參數類型即可,確保前端和后臺的參數類型一致,就可以接收并處理;
缺點,當參數過多時,建議使用對象,不然隨著業務改動,可能需要對象參數列表進行修改,導致出現一些不必要的異常,比如415狀態碼和403狀態碼異?;蛘呤?00狀態碼異常。
?
第二種,通過HttpServletRequest
?
第三種,使用Map
注意,使用Map的話,記得在參數列表中加上@RequestParam,否則會發現參數無法傳過來。
?
這三種如果都用于Ajax異步交互,其本質可以發現都是通過獲取鍵來得到值。
當然了,再本質,就是基于HTTP請求。
?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
- 上一篇: 小程序存emoji表情 不改变数据库
- 下一篇: python中的__new__与__in