觸碰jQuery:AJAX非同步詳解
和 XML)。它並非一種新的技術,而是以下幾種原有技術的結合體。
- 使用CSS和XHTML來表示。
- 使用DOM模型來互動和動態顯示。
- 使用XMLHttpRequest來和伺服器進行非同步通訊。
- 使用javascript來繫結和呼叫。 通過AJAX非同步技術,可以在客戶端指令碼與web伺服器互動資料的過程中使用XMLHttpRequest物件來完成HTTP請求(Request)/應答(Response)模型:
- 不需要使用者等待服務端響應。在非同步派發XMLHttpRequest請求後控制權馬上就被返回到瀏覽器。介面不會出現白板,在得到伺服器響應之前還可以友好的給出一個載入提示。
- 不需要重新載入整個頁面。為XMLHttpRequest註冊一個回撥函式,待伺服器響應到達時,觸發回撥函式,並且傳遞所需的少量資料。“按需取資料”也降低了伺服器的壓力。
- 不需要使用隱藏或內嵌的框架。在XHR物件之前,模擬Ajax通訊通常使用hack手段,如使用隱藏的或內嵌的框架(
XMLHttpRequest物件(XHR) XMLHttpRequest是一套可以在Javascript、VbScript、Jscript等指令碼語言中通過http協議傳送或接收XML及其他資料的一套API。 XMLHttpRequest物件首次以ActiveX物件形式在微軟Internet Explorer(IE) 5中以引入。其他瀏覽器製造商在認識到這一物件重要性後也紛紛實現了XMLHttpRequest物件,但是以一個本地JavaScript物件而不是作為一個ActiveX物件實現。而如今,由於安全性、標準等問題,微軟已經在其IE 7中把XMLHttpRequest實現為一個本地JavaScript物件。
API 描述
客服端請求
open(method,url,async, bstrUser, bstrPassword) 規定請求的型別、URL 以及是否非同步處理請求。1) method:請求的型別,例如:POST、GET、PUT及PROPFIND。大小寫不敏感。2) url:請求的URL地址,可以為絕對地址也可以為相對地址。3) async[可選]:true(預設,非同步)或 false(同步)。註釋:當您使用async=false 時,JavaScript 會等到伺服器響應就緒才繼續執行。如果伺服器繁忙或緩慢,應用程式會掛起或停止。此時,不需要編寫onreadystatechange回撥函式,把程式碼放到 send() 語句後面即可。4) bstrUser[可選]:如果伺服器需要驗證,此處指定使用者名稱,如果未指定,當伺服器需要驗證時,會彈出驗證視窗。5) bstrPassword[可選]:驗證資訊中的密碼部分,如果使用者名稱為空,則此值將被忽略。
getRequestHeader(name) 獲取指定的相應頭部資訊
setRequestHeader(name,value) 自定義HTTP頭部資訊。需在open()方法之後和send()之前呼叫,才能成功傳送請求頭部資訊。傳送門:HTTP 頭部詳解
Accept
瀏覽器能夠處理的媒體型別
Accept-Charset
瀏覽器申明自己接收的字符集
Accept-Encoding
瀏覽器申明自己接收的編碼方法,通常指定壓縮方法,是否支援壓縮,支援什麼壓縮方法(gzip,deflate)
Host
客戶端指定要請求的WEB伺服器的域名/IP 地址和埠號
Referer
發出請求的頁面的URI
Content-Type
標明發送或者接收的實體的MIME型別。傳送門:1、HTTP Content-type對照表2、格式:Content-Type: [type]/[subtype]; parameter
X-Requested-With
非標準HTTP頭,只為firefox3標註是否為ajax非同步請求,null表示為同步請求。
預設情況下,伺服器對POST請求和提交Web表單不會一視同仁,將Content-Type頭部資訊設定為application/x-www-form-urlencoded (模擬表單提交)
send(string) 將請求傳送到伺服器。引數string僅用於POST請求;對於GET請求的引數寫在url後面,所以string引數傳遞null。
abort() 呼叫此方法可取消非同步請求,呼叫後,XHR物件停止觸發事件,不允許訪問任何與響應相關的屬性;
服務端響應
onreadystatechange事件 對於非同步請求,如果需要對伺服器獲取和操作響應結果,則在send() 之前,需要為onreadystatechange屬性指定處理方法。該函式用於對伺服器響應進行處理。
readyState 存有XMLHttpRequest的狀態。每當readyState改變時,就會觸發onreadystatechange事件。從 0 到 4 發生變化:
0(未初始化)
物件已建立,但是尚未初始化(尚未呼叫open方法)
1(初始化)
物件已建立,尚未呼叫send方法
2(傳送資料)
send方法已呼叫,但是當前的狀態及http頭未知
3(資料傳送中)
已接收部分資料,因為響應及http頭不全,這時通過responseBody和responseText獲取部分資料會出現錯誤
4(完成)
資料接收完畢,此時可以通過responseXml和responseText獲取完整的迴應資料
status(數字表示) 返回當前請求的http狀態碼。傳送門:HTTP狀態碼一覽表(HTTP Status Code)
1xx(臨時響應)
表示臨時響應並需要請求者繼續執行操作的狀態程式碼。
2xx (成功)
表示成功處理了請求的狀態程式碼。Eg:200
3xx (重定向)
表示要完成請求,需要進一步操作。通常,這些狀態程式碼用來重定向。Eg:304
4xx(請求錯誤)
這些狀態程式碼表示請求可能出錯,導致伺服器無法正常處理。Eg:404
5xx(伺服器錯誤)
這些狀態程式碼表示伺服器在嘗試處理請求時發生內部錯誤。這些錯誤可能是伺服器本身的錯誤,而不是請求出錯。Eg:500
statusText(字元表示) 返回當前請求的狀態文字eg:OK (status:200)
responseText 將響應資訊作為字串返回
responseXML 將響應資訊格式化為Xml Document物件並返回
responseBody(只有微軟的IE支援) 將響應資訊正文以unsigned byte陣列形式返回(二進位制資料)
responseStream(只有IE的某些版本支援) 以Ado Stream物件(二進位制流)的形式返回響應資訊
getResponseHeader(name) 從響應資訊中獲取指定的http頭
getAllResponseHeaders() 獲取響應的所有http頭
overrideMimeType 通常用於重寫伺服器響應的MIME型別。Eg,正常情況下XMLHttpRequest只接收文字資料,但我們可以重寫MIME為“text/plain; charset=x-user-defined”,以欺騙瀏覽器避免瀏覽器格式化伺服器返回的資料,以實現接收二進位制資料。
一個簡單的ajax封裝:
var myAjax = {
// XMLHttpRequest IE7+, Firefox, Chrome, Opera, Safari ; ActiveXObject IE6, IE5
xhr: window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP"),
get: function (url, callback) {
this.xhr.open("get", url);
this.onreadystatechange(callback, this.xhr);
this.xhr.send(null);
},
post: function (url, data, callback) {
this.xhr.open("post", url);
this.xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
this.onreadystatechange(callback, this.xhr);
this.xhr.send(data);
},
onreadystatechange: function (func, _xhr) {
_xhr.onreadystatechange = function () {
if (_xhr.readyState == 4) {
if (_xhr.status == 200) {
func(_xhr.responseText);
}
}
}
}
}
使用:
$("#btn_nowTime1").bind("click", null
, function () {
myAjax.post("AjaxHandler.ashx", "func=GetServerTime"
, function (data) {
if (data)
alert(data);
}
);
});
XMLHttpRequest Level 2 XMLHttpRequest是一個瀏覽器介面,使得Javascript可以進行 HTTP (S) 通訊。但是,這個介面一直沒有標準化,每家瀏覽器的實現或多或少有點不同。HTML 5 的概念形成後,W3C 開始考慮標準化這個介面。2008年 2 月,提出了XMLHttpRequest Level 2 草案。
- 老版本的缺點 老版本的XMLHttpRequest物件有以下幾個缺點:
- 只支援文字資料的傳送,無法用來讀取和上傳二進位制檔案。
- 傳送和接收資料時,沒有進度資訊,只能提示有沒有完成。
- 受到"同域限制"(Same Origin Policy),只能向同一域名的伺服器請求資料。
- 新版本的功能 新版本的XMLHttpRequest物件,針對老版本的缺點,做出了大幅改進。
- 可以設定 HTTP 請求的時限。
- 可以使用FormData物件管理表單資料。
- 可以上傳檔案。
- 可以請求不同域名下的資料(跨域資源共享,Cross-origin resource sharing,簡稱 CORS)。
- 可以獲取伺服器端的二進位制資料。
- 可以獲得資料傳輸的進度資訊。
- 介紹幾個XMLHttpRequest Leve2 新增的成員
超時時限
timeout 設定ajax請求超時時限,過了這個時限,就自動停止 HTTP 請求。
ontimeout事件 當ajax超過timeout 時限時觸發的回撥函式。
指定響應格式
responseType (預設:“text”)在傳送請求前,根據您的資料需要,將xhr.responseType設定為“text”、“arraybuffer”、“blob”或“document”。
response 成功傳送請求後,xhr的響應屬性會包含DOMString、ArrayBuffer、Blob 或 Document 形式(具體取決於responseTyp的設定)的請求資料。
進度資訊
progress 事件 在XMLHttpRequest物件傳遞資料的時候用來返回進度資訊。它分成上傳和下載兩種情況。下載的 progress 事件屬於XMLHttpRequest物件,上傳的 progress 事件屬於XMLHttpRequest.upload物件。即:xhr.onprogress = updateProgress;xhr.upload.onprogress = updateProgress;XHR還新增了與progress事件相關的五個事件:1) load 事件:傳輸成功完成。2) abort 事件:傳輸被使用者取消。3) error 事件:傳輸中出現錯誤。4) loadstart事件:傳輸開始。5) loadEnd事件:傳輸結束,但是不知道成功還是失敗。
- 一個新功能例項
-
接收二進位制資料(方法A:改寫MIMEType) 老版本的XMLHttpRequest物件,只能從伺服器取回文字資料。但我們可以改寫資料的MIMEType,將伺服器返回的二進位制資料偽裝成文字資料,並且告訴瀏覽器這是使用者自定義的字符集。 關鍵程式碼如下: 服務端
String str = "二進位制資料獲取"; MemoryStream _memory = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(_memory, str); _memory.Position = 0; byte[] read = new byte[_memory.Length]; _memory.Read(read, 0, read.Length); _memory.Close(); context.Response.ContentType = "text/plain"; // 伺服器使用OutputStream輸出二進位制流 context.Response.OutputStream.Write(read, 0, read.Length);
客服端
$("#btn_mime").bind("click", null
, function () {
$.ajax("AjaxHandler.ashx?func=GetBinaryData",
{
type: "get",
dataType: "text",
cache: false,
mimeType: "text/plain; charset=x-user-defined",
success: function (data) {
if (data) {
var byte = [];
for (var i = 0, len = data.length; i < len; ++i) {
var c = data.charCodeAt(i);
byte[byte.length] = c & 0xff;
}
alert(byte);
}
}
});
});
瀏覽器會把相應資料當做文字資料接收,所以我們還必須再一個個位元組地還原成二進位制資料。位運算"c & 0xff",表示在每個字元的兩個位元組之中,只保留後一個位元組,將前一個位元組扔掉。原因是瀏覽器解讀字元的時候,會把字元自動解讀成Unicode 的 0xF700-0xF7ff 區段。 截圖如下:(測試環境:Google Chrome 版本 26.0.1410.43) 伺服器端返回二進位制資料:
客服端輸出: a) 使用mimeType: "text/plain; charset=x-user-defined"引數。
b) 沒有對伺服器的MIME型別進行重寫,導致返回資訊被瀏覽器格式化後輸出的二進位制資料與伺服器不同。並且不同瀏覽器格式化後輸出的二進位制資料都有差異。
- 接收二進位制資料(方法B:responseType屬性) 在XMLHttpRequest Level2中,可以使用新增的responseType屬性從伺服器取回二進位制資料。把responseType設為 blob,表示伺服器傳回的是二進位制物件。 var xhr = new XMLHttpRequest(); xhr.open (“GET”, “/path/to/image.png”); xhr.responseType = “blob”;
接收資料的時候,用瀏覽器自帶的 Blob 物件即可。注意,讀取的xhr.response,而不是xhr.responseText。 var blob = new Blob ([xhr.response], {type: “image/png”});
還可以將responseType設為arraybuffer,把二進位制資料裝在一個數組裡。然後再遍歷這個陣列。
var xhr = new XMLHttpRequest ();
xhr.open ("GET", "/path/to/image.png");
xhr.responseType = "arraybuffer";
var arrayBuffer = xhr.response;
if (arrayBuffer) {
var byteArray = new Uint8Array (arrayBuffer);
for (vari = 0; i<byteArray.byteLength; i++) {
// do something
}
}
- 更多XMLHttpRequest Level 2新功能描述請看:
- XMLHttpRequest 增強功能
- XMLHttpRequest Level 2 使用指南
- XMLHttpRequest2 新技巧
jQuery框架的Ajax jQuery是一個快速、簡單的JavaScript library,核心理念是write less,do more(寫的更少,做的更多)。它簡化了HTML 檔案的traversing,事件處理、動畫、Ajax 互動,從而方便了網頁製作的快速發展。jQuery是為改變你編寫JavaScript 的方式而設計的。更多jQuery科普知識請看:jQuery百度百科(Eg:模組,歷史版本) 下面介紹下jQuery框架中ajax相關API: 版本Jquery-1.7.1.js。
- jQuery.ajax( [url,] options ) 通過 HTTP 請求載入遠端資料。 返回值:$.ajax() 返回jqXHR物件(jqXHR物件:為XMLHttpRequest物件的超集)。可用於手動終止請求abort()、為ajax函式設定額外的回撥函式等。
ajax內部實現的兩個重要物件:s物件和jqXHR物件。
- s物件 由預設設定jQuery.ajaxSettings物件、options引數集合和jQuery.ajaxSetup({})預設設定合併而成s物件。
引數名 描述
可由ajax的options引數設定
url (預設: 當前頁地址) 要請求的目的URL地址。
usernamepassword 用於響應HTTP訪問認證請求的使用者名稱及密碼
type (預設: “GET”) 請求方式 (“POST” 或 “GET”)。注意:其它 HTTP 請求方法,如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支援。
dataType 預期伺服器返回的資料型別。如果不指定,jQuery將自動根據 HTTP 包 MIME 資訊來智慧判斷,比如 XML MIME 型別就被識別為 XML。隨後伺服器端返回的資料會根據這個值解析後,傳遞給回撥函式。必須確保網頁伺服器報告的 MIME 型別與我們選擇的dataType所匹配。比如說,XML的話,伺服器端就必須宣告 text/xml 或者 application/xml 來獲得一致的結果。可用值:
"xml"
返回 XML 文件,可用jQuery處理。
"html"
返回純文字 HTML 資訊;包含的 script 標籤會在插入dom時執行。
"script"
返回純文字 JavaScript 程式碼,常常用於跨域請求。不會觸發全域性事件和區域性事件;只支援GET方式(POST請求會自動轉化為GET請求);預設不啟用快取(cache:false)
"json"
返回 JSON 資料。JSON 資料是一種能很方便通過 JavaScript 解析的結構化資料。
"jsonp"
JSONP 格式,用於跨域請求。
"text"
返回純文字字串
其中,text 和 xml 型別返回的資料不會經過處理。資料僅僅簡單的將XMLHttpRequest的responseText或responseHTML屬性傳遞給 success 回撥函式。如果指定了 script 或者jsonp型別,那麼當從伺服器接收到資料時,實際上是用了<script>標籤而不是XMLHttpRequest物件。這種情況下,$.ajax() 不再返回一個XMLHttpRequest物件,並且也不會傳遞事件處理函式,比如beforeSend。
contentType (預設: “application/x-www-form-urlencoded”)標明發送或者接收的實體的MIME型別。當“非GET或HEAD請求”的HTTP請求時,會被設定為HTTP頭請求資訊。
mimeType 多用途網際網路郵件擴充套件(MIME,Multipurpose Internet Mail Extensions);用於重寫伺服器端響應的MIME型別。
data 傳送到伺服器的資料。可以是一個查詢字串,比如 key1=value1&key2=value2 ,也可以是一個對映,比如 {key1: “value1”, key2: “value2”} 。如果使用了後者的形式,則資料在傳送前會通過jQuery.param()函式轉換成查詢字串。這個處理過程也可以通過設定processData選項為false來回避。
processData (預設: true) 預設情況下,傳送到伺服器的資料(即data引數)將被轉換為字串以配合預設內容型別 “application/x-www-form-urlencoded”。如果要傳送 DOM 樹資訊或其它不希望轉換的資訊,請設定為 false。jQuery中的處理方式:
if ( s.data&&s.processData&&typeofs.data !== "string" ) {
s.data = jQuery.param(s.data, s.traditional );
}
async (預設: true) 預設設定下,所有請求均為非同步請求。如果需要傳送同步請求,請將此選項設定為 false。注意,同步請求將鎖住瀏覽器,使用者其它操作必須等待請求完成才可以執行。
timeout 設定請求超時時間(毫秒)。通過setTimeout(fn,time)實現。
cache (預設: true)dataType為 script 和jsonp時預設為 false。設定為 false 將不快取此頁面。當使用GET或HEAD方式傳送請求時要新增時間戳引數 (net Date()).getTime() 來保證每次傳送的URL不同, 可以避免瀏覽器快取.(只有GET和HEAD方式的請求瀏覽器才會快取)jQuery中的處理方式:
if ( s.cache === false ) {
var ts = jQuery.now(),
// rts = /([?&])_=[^&]*/嘗試替換
ret = s.url.replace( rts, "$1_=" + ts );
// rquery = /\?/如果沒有替換任何內容,則把時間戳加到url最後
s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" );
}
示例:/AjaxHandler.ashx?func=GetBinaryData&_=1368424995535
ifModified (預設: false) 僅在伺服器資料改變時獲取新資料。通過響應頭If-Modified-Since、IF-None-Match和請求頭Last-Modified、Etag提高GET或HEAD方式請求效率。(只有GET和HEAD方式的請求瀏覽器才會快取)
global (預設: true) 是否觸發全域性 AJAX 事件。設定為 false 將不會觸發全域性AJAX 事件:ajaxStart、ajaxSend、ajaxSuccess、ajaxError、ajaxComplete、ajaxStop。(比如請求頻繁時可禁用全域性AJAX事件提高效率)
context (預設:true) 這個物件用於設定Ajax相關回調函式的上下文,讓回撥函式內this指向這個物件。如果不設定這個引數,那麼回撥函式中的this就指向呼叫本次AJAX請求時傳遞的options引數載體“s物件”。但對於全域性Ajax事件來說,this都是指向全域性事件所繫結的元素。
jsonp 指定獲得jsonp回撥函式名的引數名(預設為:callback)。這個值用來替代URL中"callback=?"裡的"callback"部分,比如{jsonp:“onJsonPLoad”}會替換為將"onJsonPLoad=?"傳給伺服器。
jsonpCallback 為jsonp請求指定一個回撥函式名。jsonpCallback引數一般為字串,也可接收函式(該函式返回字串)。預設情況下生成隨機函式名:“jQuery” + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, “” ) + jQuery.now()
crossDomain (預設:null)false:同域請求;true跨域請求。倘若crossDomain標識為null,則jQuery會自動根據本地url、埠來解析。可以根據需求直接賦值來提高效能。通常情況下由伺服器自動解析即可,但如果你想在同一域中強制跨域請求(像JSONP一樣),那麼將crossDomain為true,這允許你將伺服器端重定向到另一個域。
scriptCharset 只有當請求時dataType為"jsonp"或"script",並且type是"GET"才會用於修改charset。因為此時是動態建立
hearders (預設:{}) 設定HTTP請求頭資料"{鍵:值}"。此設定發生在:jQuery所有影響HTTP頭的引數(options)設定之後,beforeSend回撥函式之前。
statusCode (預設:{}) 定義一組HTTP狀態碼與回撥函式的對映,當響應的狀態碼有匹配statusCode則會觸發對應回撥函式。例如,如果響應狀態是404,將觸發以下警報: $.ajax({ statusCode: {404: function() { alert(“page not found”); } }); 複製程式碼
traditional 如果你想要用傳統的方式來序列化資料,那麼就設定為true。請參考$.param()深度遞迴詳解。
xhrFields 宣告附加到XMLHttpRequest物件的自定義“key-value”陣列。例如,如果需要的話,你可以用它來設定跨域的withCredentials為true,即:xhrFields: { withCredentials: true }
5個區域性事件 beforeSend、dataFilter、success、error、complete。(詳見後面事件介紹部分)
由ajax函式內部解析或內部提供
dataTypes 由dataType按空格拆分所得。
isLocal 根據協議確定當前url請求的是否為本地請求。jQuery中定義預設值為: isLocal:/(?:about|app|app-storage|.+-extension|file|res|widget)?/.test(/([\w+.-]+:)(??/([^/?#:]*)(?:?\d+))?)?/.exec(url))
hasContent 非GET或HEAD請求為true,用於處理data和contentType引數。
contents 一個"{型別字串:正則表示式}"的物件,倘若dataTypes[0]為“*”時,用contents中的正則表示式去匹配contentType,匹配成功則用“型別字串”覆蓋dataTypes[0]。jQuery內部定義如下:
contents: {
xml: /xml/,
html: /html/,
json: /json/,
script: /javascript|ecmascript/
}
accepts 瀏覽器能夠處理的媒體型別,其值取決於dataTypes[0]引數。jQuery內部定義如下:
accepts: {
xml: "application/xml, text/xml",
html: "text/html",
text: "text/plain",
json: "application/json, text/javascript",
script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript",
"*": allTypes // dataTypes[0]匹配不上時取此值
}
responseFields jqXHR超集設定“資料型別:屬性”對應關係,在返回響應資料時,用於確定建立哪個屬性變數。jQuery中定義如下:
responseFields: {
xml: "responseXML",
text: "responseText"
}
converters 儲存資料型別對應的轉換器,根據dataTypes獲取對應轉換器,用於對響應資料response進行處理。該處理髮生在dataFilter回撥函式之後。
converters: {
"* text": window.String,
"text html": true,
"text json": jQuery.parseJSON,
"text xml": jQuery.parseXML,
"text script": function( text ) {
jQuery.globalEval( text ); // 執行指令碼
return text;
}
}
- jqXHR物件 為不同瀏覽器內建的XMLHttpRequest提供了一致的超集。對於XMLHttpRequest之外的傳輸機制,比如JSONP請求,jXHR物件也可以進行處理。
超集與真子集: 如果一個集合S2中的每一個元素都在集合S1中,且集合S1中可能包含S2中沒有的元素,則集合S1就是S2的一個超集。 S1是S2的超集,則S2是S1的真子集,反之亦然。
jqXHR物件我們常常使用如下成員,這些成員主要用於ajax的全域性事件和區域性事件,並且做為$.ajax()函式返回值返回。
jqXHR:{
readyState
,setRequestHeader: function( name, value )
,getAllResponseHeaders: function()
,getResponseHeader: function( key )
,overrideMimeType: function( type )
,abort: function( statusText )
,responseText
,responseXML
}
另外,jqXHR的全部成員如下:
在圖中我們看到一些陌生的函式,比如:done()、fail()、promise()、isResolve()、isRejected()、then()、always()、progress()等,都是jQuery的deferred物件API。
開發網站的過程中,我們經常遇到某些耗時很長的javascript操作。其中,既有非同步的操作(比如ajax讀取伺服器資料),也有同步的操作(比如遍歷一個大型陣列),它們都不是立即能得到結果的。 通常的做法是,為它們指定回撥函式(callback)。即事先規定,一旦它們執行結束,應該呼叫哪些函式。但是,在回撥函式方面,jQuery的功能非常弱。為了改變這一點,jQuery開發團隊就設計了deferred物件。 簡單說,deferred物件就是jQuery的回撥函式解決方案。在英語中,defer的意思是"延遲",所以deferred物件的含義就是"延遲"到未來某個點再執行。 它解決了如何處理耗時操作的問題,對那些操作提供了更好的控制,以及統一的程式設計介面。 更專業的資源:jQuery的deferred物件詳解
- jQuery Ajax事件 jQuery框架中,伴隨Ajax請求會觸發若干事件,我們可以訂閱這些事件並在其中處理我們的邏輯。在jQuery中有兩種Ajax事件:區域性事件和全域性事件。
- 區域性事件(回撥函式),在$.ajax()方法的options引數中宣告,可以用來設定請求資料和獲取、處理響應資料。
beforeSend 該函式可在傳送請求前修改XMLHttpRequest物件,如新增自定義 HTTP 頭。簽名:function (jqXHR,s) { }函式說明:傳入jqXHR、s物件
dataFilter 在請求成功之後呼叫。若狀態碼為304(未修改)則不觸發此回撥。簽名:function (data, dataType) { return newData; }函式說明:傳入返回的資料、"dataType"引數的值。並且必須返回新的資料傳遞給success回撥函式
success 請求成功時觸發。簽名:function (data,statusText,jqXHR) { }函式說明:傳入返回的資料、描述狀態的字串”success”、jqXHR物件
error 請求失敗時呼叫此函式。簽名:function (jqXHR, textStatus, errorThrown) { }函式說明:傳入jqXHR物件、描述狀態的字串”error”、錯誤資訊
complete 請求完成後回撥函式 (請求成功或失敗之後均呼叫)簽名:function (jqXHR, textStatus) { }函式說明:傳入jqXHR物件、描述狀態的字串(可能值:“No Transport”、“timeout”、“notmodified”—304 "、“parsererror”、“success”、“error”)
定義方式例如:
$.ajax({
// ...
beforeSend: function(){
// Handle the beforeSend event
},
complete: function(){
// Handle the complete event
}
// ...
});
複製程式碼 2) 全域性事件,每次Ajax請求都會觸發,它會向DOM中的所有元素廣播,你只需為DOM中任意元素bind好全域性事件即會觸發(若繫結多次,則會依次觸發為事件註冊的回撥函式)。
ajaxStart 開始新的Ajax請求,並且此時jQuery物件上沒有其他ajax請求正在進行。簽名:function(e)函式說明:傳入事件物件
ajaxSend 當一個Ajax請求開始時觸發簽名:function(e,jqXHR,s)函式說明:傳入事件物件、jqXHR、s物件
ajaxSuccess 全域性的請求成功簽名:function(e,jqXHR,s,data)函式說明:傳入事件物件、jqXHR、s物件、請求成功返回的相應資料
ajaxError 全域性的發生錯誤時觸發簽名:function(e,jqXHR,s,errorData)函式說明:傳入事件物件、jqXHR、s物件、請求失敗返回的錯誤資訊
ajaxComplete 全域性的請求完成時觸發簽名:function(e,jqXHR,s)函式說明:傳入事件物件、jqXHR、s物件
ajaxStop 當jQuery物件上正在進行Ajax請求都結束時觸發。簽名:function(e)函式說明:傳入事件物件
全域性事件在jQuery中的宣告方式:
jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){
jQuery.fn[ o ] = function( f ){
return this.on( o, f );
};
});
所以我們可以使用下面兩種方式定義全域性事件:
// 可以用bind來繫結,用unbind來取消繫結。 $("#loading").bind(“ajaxSend”, function(){ … }); 或者: $("#loading").ajaxStart(function(){ … }); 複製程式碼 3) ajax方法完整的事件流
-
示例:$.ajax()觸發的事件(區域性事件和全域性事件)
// 全域性事件 $("#div_event").ajaxStart(function (e) { doAddEvent4textarea("txt_event", "觸發ajaxStart回撥函式"); }); $("#div_event").ajaxSend(function (e) { doAddEvent4textarea("txt_event", "觸發ajaxSend回撥函式"); }); $("#div_event").ajaxSuccess(function (e, jqXHR, s, data) { doAddEvent4textarea("txt_event", "觸發ajaxSuccess回撥函式"); }); $("#div_event").ajaxError(function (e, jqXHR, s, errorData) { doAddEvent4textarea("txt_event", "觸發ajaxError回撥函式"); }); $("#div_event").ajaxComplete(function (e, jqXHR, s) { doAddEvent4textarea("txt_event", "觸發ajaxComplete回撥函式"); }); $("#div_event").ajaxStop(function (e) { doAddEvent4textarea("txt_event", "觸發ajaxStop回撥函式"); }); // 區域性事件 function bindLocalEvent(e) { var textareaid = e.data.textareaid; var global = e.data.global; $.ajax("AjaxHandler.ashx?func=btn_nowTime_long", { type: "get", dataType: "text", global: global, cache: false, beforeSend: function (jqXHR, s) { doAddEvent4textarea(textareaid, "觸發beforeSend回撥函式"); }, dataFilter: function (data, dataType) { doAddEvent4textarea(textareaid, "觸發dataFilter回撥函式"); }, success: function (data, statusText, jqXHR) { doAddEvent4textarea(textareaid, "觸發success回撥函式"); }, error: function (jqXHR, textStatus, errorThrown) { doAddEvent4textarea(textareaid, "觸發error回撥函式"); }, complete: function (jqXHR, textStatus) { doAddEvent4textarea(textareaid, "觸發complete回撥函式"); } }); } function doAddEvent4textarea(textareaid, txt) { var textarea = $("#" + textareaid); textarea.val(textarea.val() + "\r\n" + txt); }
-
.ajax()加上beforeSend、success、complete回撥函式,在回撥函式中加上處理提示框。 b) 使用全域性事件的做法是:
$(document).ajaxStart(onStart)
.ajaxComplete(onComplete)
.ajaxSuccess(onSuccess);
function onStart(event) { //..... }
function onComplete(event, xhr, settings) { //..... }
function onSuccess(event, xhr, settings) { //..... }
- jQuery ajax相關函式
- jQuery.ajaxSetup({ }) jQuery.ajax()函式中的所有的引數選項都可以通過jQuery.ajaxSetup()函式來全域性設定預設值。
- $.ajax()函式的封裝 a) $("").load(url [, params] [, callback]) 請求遠端的HTML檔案程式碼(dataType: “html”),預設使用 GET 方式,如果傳遞了params引數則使用Post方式。在請求“成功”完成時將responseText屬性值插入至DOM中。但不管請求是否成功完成“在最後”都會執行callback回撥函式(即:complete:callback)。 b) jQuery.get(url [, data] [, callback] [, type] ) 通過HTTP GET請求載入資料,並在請求成功時執行回撥函式(即:success: callback)。 c) jQuery.getJSON(url [, data] [, callback] ) 通過 HTTP GET 請求載入 JSON 資料。相當於: jQuery.get(url, [data],[callback], “json”) 可以通過使用JSONP 形式的回撥函式來載入其他網域的JSON資料。 d) jQuery.getScript(url [, callback] ) 通過 HTTP GET 請求載入並執行一個 JavaScript 檔案。相當於: jQuery.get(url, null, [callback], “script”) 可以跨域呼叫 JavaScript 檔案。 e) jQuery.post(url [, data] [, callback] [, type] ) 通過 HTTP POST 請求載入資訊,並在請求成功時執行回撥函式(即:success: callback)。
- 物件序列化 a) jQuery.param(object,traditional) 建立陣列或物件的序列化表示,該序列化可在ajax請求時在URL查詢字串中使用。
序列化過程中會使用encodeURIComponent()函式把字串作為URI元件進行編碼。 encodeURIComponent() 方法不會對 ASCII 字母和數字進行編碼,也不會對這些 ASCII 標點符號進行編碼: - _ . ! ~ * " ( ) 。其他字元(比如:;/??&=+$,# 這些用於分隔 URI 元件的標點符號),都是由一個或多個十六進位制的轉義序列替換的。 // 在param中會進行如下處理
function( key, value ) {
// 如果value是函式,則取其函式返回值
value = jQuery.isFunction( value ) ? value() : value;
s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
};
對於 jQuery 1.4,.param()深度遞迴詳解和$.param() 示例 b)