標籤:fun 電話 on() 而不是 參數類型 互動 用戶端 介面測試 body
昨天還沒有談完,今天做一個瞭解。
首先還是以錯誤,來講述。
一、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,這個通常就是服務端代碼有問題了。這個就要根據具體的調試情況來看了。比如null 指標或者是類型轉換異常等等。
二、如何調試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,使用者必須首先在Proxy 伺服器上得到授權
408——用戶端沒有在使用者指定的餓時間內完成請求
409——對當前資源狀態,請求不能完成
410——伺服器上不再有此資源且無進一步的參考地址
411——伺服器拒絕使用者定義的Content-Length屬性請求
412——一個或多個要求標頭欄位在當前請求中錯誤
413——請求的資源大於伺服器允許的大小
414——請求的資源URL長於伺服器允許的長度
415——請求資源不支援要求項目格式
416——請求中包含Range要求標頭欄位,在當前請求資源範圍內沒有range指示值,請求也不包含If-Range要求標頭欄位
417——伺服器不滿足請求Expect頭欄位指定的期望值,如果是Proxy 伺服器,可能是下一級伺服器不能滿足請求
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,並作為回呼函數參數傳遞。可用的類型如下:
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狀態代碼異常或者是500狀態代碼異常。
第二種,通過HttpServletRequest
第三種,使用Map
注意,使用Map的話,記得在參數列表中加上@RequestParam,否則會發現參數無法傳過來。
這三種如果都用於Ajax非同步互動,其本質可以發現都是通過擷取鍵來得到值。
當然了,再本質,就是基於HTTP請求。
談談Ajax(二)