1. 程式人生 > >觸碰jQuery:AJAX非同步詳解

觸碰jQuery:AJAX非同步詳解

和 XML)。它並非一種新的技術,而是以下幾種原有技術的結合體。

  1. 使用CSS和XHTML來表示。
  2. 使用DOM模型來互動和動態顯示。
  3. 使用XMLHttpRequest來和伺服器進行非同步通訊。
  4. 使用javascript來繫結和呼叫。 通過AJAX非同步技術,可以在客戶端指令碼與web伺服器互動資料的過程中使用XMLHttpRequest物件來完成HTTP請求(Request)/應答(Response)模型:
  5. 不需要使用者等待服務端響應。在非同步派發XMLHttpRequest請求後控制權馬上就被返回到瀏覽器。介面不會出現白板,在得到伺服器響應之前還可以友好的給出一個載入提示。
  6. 不需要重新載入整個頁面。為XMLHttpRequest註冊一個回撥函式,待伺服器響應到達時,觸發回撥函式,並且傳遞所需的少量資料。“按需取資料”也降低了伺服器的壓力。
  7. 不需要使用隱藏或內嵌的框架。在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 草案。

  1. 老版本的缺點 老版本的XMLHttpRequest物件有以下幾個缺點:
  1. 只支援文字資料的傳送,無法用來讀取和上傳二進位制檔案。
  2. 傳送和接收資料時,沒有進度資訊,只能提示有沒有完成。
  3. 受到"同域限制"(Same Origin Policy),只能向同一域名的伺服器請求資料。
  1. 新版本的功能 新版本的XMLHttpRequest物件,針對老版本的缺點,做出了大幅改進。
  1. 可以設定 HTTP 請求的時限。
  2. 可以使用FormData物件管理表單資料。
  3. 可以上傳檔案。
  4. 可以請求不同域名下的資料(跨域資源共享,Cross-origin resource sharing,簡稱 CORS)。
  5. 可以獲取伺服器端的二進位制資料。
  6. 可以獲得資料傳輸的進度資訊。
  1. 介紹幾個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事件:傳輸結束,但是不知道成功還是失敗。

  1. 一個新功能例項
  1. 接收二進位制資料(方法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型別進行重寫,導致返回資訊被瀏覽器格式化後輸出的二進位制資料與伺服器不同。並且不同瀏覽器格式化後輸出的二進位制資料都有差異。

  1. 接收二進位制資料(方法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
    }
}
  1. 更多XMLHttpRequest Level 2新功能描述請看:
  1. XMLHttpRequest 增強功能
  2. XMLHttpRequest Level 2 使用指南
  3. 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。

  1. jQuery.ajax( [url,] options ) 通過 HTTP 請求載入遠端資料。 返回值:$.ajax() 返回jqXHR物件(jqXHR物件:為XMLHttpRequest物件的超集)。可用於手動終止請求abort()、為ajax函式設定額外的回撥函式等。

ajax內部實現的兩個重要物件:s物件和jqXHR物件。

  1. 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;
                }
}
  1. 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物件詳解

  1. jQuery Ajax事件 jQuery框架中,伴隨Ajax請求會觸發若干事件,我們可以訂閱這些事件並在其中處理我們的邏輯。在jQuery中有兩種Ajax事件:區域性事件和全域性事件。
  1. 區域性事件(回撥函式),在$.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方法完整的事件流

  1. 示例:$.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);
       }
    
  2. .ajax()ajaxajaxajaxajaxajaxa)使.ajax()方法的全域性事件典型用例 你的頁面存在多個甚至為數不少的ajax請求,但是這些ajax請求都有相同的訊息機制。ajax請求開始前顯示一個提示框,提示“正在讀取資料”;ajax請求成功時提示框顯示“資料獲取成功”;ajax請求結束後隱藏提示框。 a) 不使用全域性事件的做法是: 給.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) { //..... }
  1. jQuery ajax相關函式
  1. jQuery.ajaxSetup({ }) jQuery.ajax()函式中的所有的引數選項都可以通過jQuery.ajaxSetup()函式來全域性設定預設值。
  2. $.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)。
  3. 物件序列化 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()便PHPRubyonRailstraditional=trueajaxtraditionaloptions.param() 方法將會通過深度遞迴的方式序列化物件,以便符合現代化指令碼語言的需求,比如 PHP、Ruby on Rails 等。你可以傳遞traditional = true 或在ajax功能中傳遞包含traditional的options引數。 傳送門:.param()深度遞迴詳解和$.param() 示例 b) (&quot;&quot;).serializeArray()inputtextareaformjQueryJSONJSON使name(&quot;&quot;).serializeArray() 可以將一個或多個表單元素(比如 input、 textarea等),或者 form 元素本身的jQuery物件序列化為JSON物件。(非 JSON 字串。需要使用外掛或者第三方庫進行字串化操作) 特別說明,元素不能被禁用(禁用的元素不會被包括在內),並且元素應當有含有 name 屬性。提交按鈕的值也不會被序列化。檔案選擇元素的資料也不會被序列化。 傳送門:

相關推薦

jQueryAJAX非同步

和 XML)。它並非一種新的技術,而是以下幾種原有技術的結合體。 使用CSS和XHTML來表示。 使用DOM模型來互動和動態顯示。 使用XMLHttpRequest來和伺服器進行非同步通訊。 使用javascript來繫結和呼叫。 通過AJAX非同步技術,可以

jQuery之$.ajax()方法

ajax不管是前端,還是後臺都是要學習的知識點,也是必用知識點。ajax是非同步更新,只需要進行少量的資料互動便可到達頁面的區域性刷下。非常棒。 jquery中的ajax方法引數總是記不住,這裡記錄一下。 1.url:  要求為String型別的引數,(預設為當前

JQueryajax屬性

jquery中的ajax方法引數總是記不住,這裡記錄一下。 1.url:  要求為String型別的引數,(預設為當前頁地址)傳送請求的地址。 2.type:  要求為String型別的引數,請求方式(post或get)預設為get。注意其他http請求方法,例如pu

jqueryajax方法

1.url:要求為String型別的引數,傳送請求的地址(預設是當前網頁地址)2.type:String型別的引數,請求方式(post或get,預設為get)。請注意其他http的請求方法。3.timeout:Number型別的引數,設定請求超過時間(ms)。此設定將覆蓋$.

jQuery中的$.ajax()方法

jquery中的ajax方法引數總是記不住,這裡記錄一下。   1.url:  要求為String型別的引數,(預設為當前頁地址)傳送請求的地址。 2.type:  要求為String型別的引數,請求方式(post或get)預設為get。注意其他http請求

JSjquery.dataTables.bootstrap外掛

dataTable介紹 DataTables is a plug-in for the jQuery Javascript library. It is a highly flexible tool, build upon the foundations of progressiv

[jQuery]$.ajax()方法及例項

$.ajax()方法詳解及例項  1.url: 要求為String型別的引數,(預設為當前頁地址)傳送請求的地址。2.type:要求為String型別的引數,請求方式(post或get)預設為get。注意其他http請求方法,例如put和delete也可以使用,但僅部分瀏覽

JQuery ajax 屬性

url: String 型別的引數。(預設為當前頁地址)傳送請求的地址 type: String型別的引數,請求方式(post或get)預設為get。 注意其他http請求方法例如put和delete也可以使用,但是僅部分瀏覽器支援。 t

jQuery ajax引數

The $.ajax() function underlies all Ajax requests sent by jQuery. It is often unnecessary to directly call this function, as several higher-level alterna

$.ajax()方法

例如 lencod ace 包含 等等 json 返回 用戶名 代碼 jquery中的ajax方法參數總是記不住,這裏記錄一下。 1.url: 要求為String類型的參數,(默認為當前頁地址)發送請求的地址。 2.type: 要求為String類型的參數,請求方式(p

Linuxat命令

計時 osi 執行 inux days pan 必須 man 一個 at命令 at命令為單一工作調度命令。at命令非常簡單,但是在指定時間上卻非常強大 語法 at [選項] time at > 執行的命令 ctrl+d 選項 -m :當指定的任務被

WebApi 接口參數不再困惑傳參

gin ebr 字符流 sts ash nbsp 之前 ret 傳遞對象 轉自:http://www.cnblogs.com/landeanfen/p/5337072.html 閱讀目錄 一、get請求 1、基礎類型參數 2、實體作為參數 3、數組作為

jQuery.extend 函數

而且 卻又 命名空間 什麽 介紹 常用 new end 空間 JQuery的extend擴展方法: Jquery的擴展方法extend是我們在寫插件的過程中常用的方法,該方法有一些重載原型,在此,我們一起去了解了解。 一、Jquery的擴展方法原型是: 

OSPF之三OSPF LSA

ospf lsa詳解 forwarding address OSPF LSA詳解OSPF V2版本中常用的主要有6類LSA,分別是Router-LSA、Network-LSA、Network-summary-LSA、ASBR-summary-LSA、AS-External-LSA、NSSA-LSA,接

jQuery Validate驗證框架

lec false 樣式 廈門 adding 常用 invalid util 類名 jQuery校驗官網地址:http://bassistance.de/jquery-plugins/jquery-plugin-validation 一、導入js庫 <scri

大型網站架構系列負載均衡(3)

lte 子進程 變化 rewrite acc smtp alived 傳輸 操作 本次分享大綱 軟件負載均衡概述 Ngnix負載均衡 Lvs負載均衡 Haproxy負載均衡 本次分享總結 一、軟件負載均衡概述 硬件負載均衡性能優越,功能全面,但是價格昂貴,一般適合初期或

Android零基礎入門第19節Button使用

用戶界面 ket 派生 觸發 eat c99 list 一個 blank Button(按鈕)是Android開發中使用非常頻繁的組件,主要是在UI界面上生成一個按鈕,該按鈕可以供用戶單擊,當用戶單擊按鈕時,按鈕會觸發一個onClick點擊事件。 一、Button

Hadoop學習筆記MapReduce框架

object 好的 單點故障 提高 apr copy 普通 exce 代表性 開始聊mapreduce,mapreduce是hadoop的計算框架,我學hadoop是從hive開始入手,再到hdfs,當我學習hdfs時候,就感覺到hdfs和mapreduce關系的緊密。這個

Java必知必會異常機制

賦值 輸出結果 類庫 負數 虛擬 類名 通過反射 基於 all 一、Java異常概述 在Java中,所有的事件都能由類描述,Java中的異常就是由java.lang包下的異常類描述的。 1、Throwable(可拋出):異常類的最終父類,它有兩個子類,Error與Exce

PHP源代碼分析Zend HashTable

for a算法 rec calloc() 無符號 調用 模擬 散列表 tables 最近看了篇關於php內的hashtable的文章,PHP數據存儲的核心,各種常量、變量、函數、類、對象等都用它來組織的。轉載地址 http://www.phppan.com/2009/12/