jQuery學習之旅 Item10 ajax快餐

1. 摘要

本系列文章將帶您進入jQuery的精彩世界, 其中有不少做者具體的使用經驗和解決方案, 即便你會使用jQuery也能在閱讀中發現些許祕籍.
本篇文章講解如何使用jQuery方便快捷的實現Ajax功能.統一全部開發人員使用Ajax的方式.javascript

2. 前言

Ajax讓用戶頁面豐富起來, 加強了用戶體驗. 使用Ajax是全部Web開發的必修課. 雖然Ajax技術並不複雜, 可是實現方式仍是會由於每一個開發人員的而有所差別.jQuery提供了一系列Ajax函數來幫助咱們統一這種差別, 而且讓調用Ajax更加簡單.css

3. 原始Ajax與jQuery中的Ajax

首先經過實例, 來看一下jQuery實現Ajax有多簡單. 下面是一個使用原始Ajax的示例:html

<html>
<head>
    <title>jQuery Ajax</title>
    <script type="text/javascript"> $(function() { var xhr = new AjaxXmlHttpRequest(); $("#btnAjaxOld").click(function(event) { var xhr = new AjaxXmlHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { document.getElementById("divResult").innerHTML = xhr.responseText; } } xhr.open("GET", "data/AjaxGetCityInfo.aspx?resultType=html", true); xhr.send(null); }); }) //跨瀏覽器獲取XmlHttpRequest對象 function AjaxXmlHttpRequest() { var xmlHttp; try { // Firefox, Opera 8.0+, Safari xmlHttp = new XMLHttpRequest(); } catch (e) { // Internet Explorer try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert("您的瀏覽器不支持AJAX!"); return false; } } } return xmlHttp; } </script>

</head>
<body>    
    <button id="btnAjaxOld">原始Ajax調用</button><br />
    <br />
    <div id="divResult"></div>
</body>
</html>

上面的實例中, data/AjaxGetCityInfo.aspx?resultType=html 地址會返回一段HTML代碼.java

使用原始Ajax, 咱們須要作較多的事情, 好比建立XmlHttpRequest對象, 判斷請求狀態, 編寫回調函數等.python

而用jQuery的Load方法, 只須要一句話:jquery

$("#divResult").load("data/AjaxGetCityInfo.aspx", { "resultType": "html" });

曾經我是一個原始Ajax的絕對擁護者, 甚至摒棄微軟的Asp.net Ajax, 由於我想要最高的代碼靈活度. 使用原始Ajax讓我感受完成本身的工做更加輕鬆, 即便多寫了一些代碼. 可是當我去翻看別人的Ajax代碼而且嘗試修改的時候, 我改變了個人見解——咱們的代碼處處分佈着建立XmlHttpRequest方法的函數, 或者某些Ajax程序邏輯性和結構性不好, 很難看懂.ajax

咱們能夠將通用方法放到一個js文件中, 而後告訴你們」嘿夥伴們, 都來用這個js中的方法」. 可是在某些時候有些新來的外包人員並不知道有這個js文件的存在. 並且其實這個通用的js就是一個公共的腳本類庫, 我相信沒有人會以爲本身開發一個類庫會比jQuery更好!編程

因此我放棄了製造輪子的計劃, 你們都使用jQuery編寫Ajax相關的方法就能夠解決各類差別性問題, 而且讓工做更有效率.json

如今只是用jQuery的Ajax函數, 個人頁面變得簡潔了:跨域

<html>
<head>
    <title>jQuery Ajax</title>
    <script type="text/javascript" src="scripts/jquery-1.3.2-vsdoc2.js"></script>
    <script type="text/javascript"> $(function() { $("#btnGetHtml").click(function(event) { $("#divResult").load("data/AjaxGetCityInfo.aspx", { "resultType": "html" }); }); }) </script>
</head>
<body>    
    <button id="btnAjaxJquery">使用jQuery的load方法</button>
    <br />
    <div id="divResult"></div>
</body>
</html>

4. jQuery Ajax詳解

jQuery提供了幾個用於發送Ajax請求的函數. 其中最核心也是最複雜的是jQuery.ajax( options ),全部的其餘Ajax函數都是它的一個簡化調用. 當咱們想要徹底控制Ajax時可使用此結果, 不然仍是使用簡化方法如get, post, load等更加方便. 因此jQuery.ajax( options ) 方法放到最後一個介紹. 先來介紹最簡單的load方法:

1. load( url, [data], [callback] )

Returns: jQuery包裝集

說明:

  • load方法可以載入遠程 HTML 文件代碼並插入至 DOM 中。
  • 默認使用 GET 方式, 若是傳遞了data參數則使用Post方式.
  • 傳遞附加參數時自動轉換爲 POST 方式。jQuery 1.2 中,能夠指定選擇符,來篩選載入的 HTML 文檔,DOM 中將僅插入篩選出的 HTML 代碼。語法形如 「url #some > selector」, 默認的選擇器是」body>*」.

講解:

  • load是最簡單的Ajax函數, 可是使用具備侷限性:
  • 它主要用於直接返回HTML的Ajax接口
  • load是一個jQuery包裝集方法,須要在jQuery包裝集上調用,而且會將返回的HTML加載到對象中, 即便設置了回調函數也仍是會加載.
    不過不能否認load接口設計巧妙而且使用簡單.下面經過示例來演示Load接口的使用:
<html>
<head>
    <title>jQuery Ajax - Load</title>

    <script type="text/javascript" src="../scripts/jquery-1.3.2-vsdoc2.js"></script>

    <script type="text/javascript"> $(function() { $("#btnAjaxGet").click(function(event) { //發送Get請求 $("#divResult").load("../data/AjaxGetMethod.aspx?param=btnAjaxGet_click" + "&tim estamp=" + (new Date()).getTime()); }); $("#btnAjaxPost").click(function(event) { //發送Post請求 $("#divResult").load("../data/AjaxGetMethod.aspx", { "param": "btnAjaxPost_click" }); }); $("#btnAjaxCallBack").click(function(event) { //發送Post請求, 返回後執行回調函數. $("#divResult").load("../data/AjaxGetMethod.aspx", { "param": "btnAjaxCallBack_click " }, function(responseText, textStatus, XMLHttpRequest) { responseText = " Add in the CallBack Function! <br/>" + responseText $("#divResult").html(responseText); //或者: $(this).html(responseText); }); }); $("#btnAjaxFiltHtml").click(function(event) { //發送Get請求, 從結果中過濾掉 "鞍山" 這一項 $("#divResult").load("../data/AjaxGetCityInfo.aspx?resultType=html" + "&timestamp =" + (new Date()).getTime() + " ul>li:not(:contains('鞍山'))"); }); }) </script>

</head>
<body>    
    <button id="btnAjaxGet">使用Load執行Get請求</button><br />
    <button id="btnAjaxPost">使用Load執行Post請求</button><br />
    <button id="btnAjaxCallBack">使用帶有回調函數的Load方法</button><br />
    <button id="btnAjaxFiltHtml">使用selector過濾返回的HTML內容</button>
    <br />
    <div id="divResult"></div>
</body>
</html>

上面的示例演示瞭如何使用Load方法.

提示:

  • 咱們要時刻注意瀏覽器緩存, 當使用GET方式時要添加時間戳參數 (net Date()).getTime() 來保證每次發送的URL不一樣, 能夠避免瀏覽器緩存.
  • 當在url參數後面添加了一個空格, 好比」 「的時候, 會出現」沒法識別符號」的錯誤, 請求仍是能正常發送. 可是沒法加載HTML到DOM. 刪除後問題解決.

2.jQuery.get( url, [data], [callback], [type] )

Returns: XMLHttpRequest

說明:

  • 經過遠程 HTTP GET 請求載入信息。
  • 這是一個簡單的 GET 請求功能以取代複雜 $.ajax 。請求成功時可調用回調函數。若是須要在出錯時執行函數,請使用 $.ajax

講解:

  • 此函數發送Get請求, 參數能夠直接在url中拼接, 好比:
$.get("../data/AjaxGetMethod.aspx?param=btnAjaxGet_click");

或者經過data參數傳遞:

$.get("../data/AjaxGetMethod.aspx", { "param": "btnAjaxGet2_click" });
  • 兩種方式效果相同, data參數會自動添加到請求的url中,若是url中的某個參數, 又經過data參數傳遞, 不會自動合併相同名稱的參數.

回調函數的簽名以下:

function (data, textStatus) {
  // data could be xmlDoc, jsonObj, html, text, etc
  this; // the options for this ajax request
}

其中data是返回的數據, testStatus表示狀態碼, 多是以下值:在回調函數中的this是獲取options對象的引用
type參數是指data數據的類型, 多是下面的值:
「xml」, 「html」, 「script」, 「json」, 「jsonp」, 「text」.默認爲」html」.

jQuery.getJSON( url, [data], [callback] ) 方法就至關於 jQuery.get(url, [data],[callback], 「json」)

3. jQuery.getJSON( url, [data], [callback] )

Returns: XMLHttpRequest

至關於: jQuery.get(url, [data],[callback], 「json」)

說明:

  • 經過 HTTP GET 請求載入 JSON 數據。
  • 在 jQuery 1.2 中,您能夠經過使用JSONP 形式的回調函數來加載其餘網域的JSON數據,如 「myurl?callback=?」。jQuery 將自動替換 ? 爲正確的函數名,以執行回調函數。
    注意:此行之後的代碼將在這個回調函數執行前執行。

講解:

  • getJSON函數僅僅將get函數的type參數設置爲」JSON」而已. 在回調函數中獲取的數據已是按照JSON格式解析後的對象了:
$.getJSON("../data/AjaxGetCityInfo.aspx", { "resultType": "json" }, function(data, textStatus)
{
      alert(data.length);
      alert(data[0].CityName);
});

服務器端返回的字符串以下:

[{""pkid"":""0997"",""ProvinceId"":""XJ"",""CityName"":""阿克蘇"",""CityNameEn"":""Akesu"",""PostCode"":""843000"",""isHotCity"":false},
 {""pkid"":""0412"",""ProvinceId"":""LN"",""CityName"":""鞍山"",""CityNameEn"":""Anshan"",""PostCode"":""114000"",""isHotCity"":false}]

示例中我返回的餓是一個數組, 使用data.length能夠獲取數組的元素個數, data[0]訪問第一個元素, data[0].CityName訪問第一個元素的CityName屬性.

4. jQuery.getScript( url, [callback] )

Returns: XMLHttpRequest

至關於: jQuery.get(url, null, [callback], 「script」)

說明:

  • 經過 HTTP GET 請求載入並執行一個 JavaScript 文件。
  • jQuery 1.2 版本以前,getScript 只能調用同域 JS 文件。 1.2中,您能夠跨域調用 JavaScript 文件。

講解:

之前我使用dojo類庫時官方默認的文件不支持跨域最後致使我放棄使用dojo(雖然在網上找到了能夠跨域的版本, 可是感受不夠完美). 因此我特別對這個函數的核心實現和使用作了研究.
首先了解此函數的jQuery內部實現, 仍然使用get函數, jQuery全部的Ajax函數包括get最後都是用的是jQuery.ajax(), getScript將傳入值爲」script」的type參數, 最後在Ajax函數中對type爲script的請求作了以下處理:

var head = document.getElementsByTagName("head")[0]; 
var script = document.createElement("script");
script.src = s.url;

上面的代碼動態創建了一個script語句塊, 而且將其加入到head中:

head.appendChild(script);

當腳本加載完畢後, 再從head中刪除:

// Handle Script loading
            if ( !jsonp ) {
                var done = false;

                // Attach handlers for all browsers
                script.onload = script.onreadystatechange = function(){
                    if ( !done && (!this.readyState ||
                            this.readyState == "loaded" || this.readyState == "complete") ) {
                        done = true;
                        success();
                        complete();

                        // Handle memory leak in IE
                        script.onload = script.onreadystatechange = null;
                        head.removeChild( script );
                    }
                };
            }

我主要測試了此函數的跨域訪問和多瀏覽器支持.下面是結果:

這裏寫圖片描述

下面是我關鍵的測試語句, 也用來演示如何使用getScript函數:

$("#btnAjaxGetJSON").click(function(event) {
                $.getScript("../scripts/getScript.js", function(data, textStatus) {
                    alert(data);
                    alert(textStatus);
                    alert(this.url);
                });
            });

            $("#btnAjaxGetJSONXSS").click(function(event) {
                $.getScript("http://resource.elong.com/getScript.js", function(data, textStatus) {
                    alert(data);
                    alert(textStatus);
                    alert(this.url);
                });
            });

5. jQuery.post( url, [data], [callback], [type] )

Returns: XMLHttpRequest

說明:

  • 經過遠程 HTTP POST 請求載入信息。
  • 這是一個簡單的 POST 請求功能以取代複雜 $.ajax 。請求成功時可調用回調函數。若是須要在出錯時執行函數,請使用 $.ajax

講解:

  • 具體用法和get相同, 只是提交方式由」GET」改成」POST」.

6. jQuery.ajax( options )

Returns: XMLHttpRequest

說明:

  • 經過 HTTP 請求加載遠程數據。
  • jQuery 底層 AJAX 實現。簡單易用的高層實現見 $.get, $.post 等。
  • $.ajax() 返回其建立的 XMLHttpRequest 對象。大多數狀況下你無需直接操做該對象,但特殊狀況下可用於手動終止請求。
  • $.ajax() 只有一個參數:參數 key/value 對象,包含各配置及回調函數信息。

jQuery 1.2 中,您能夠跨域加載 JSON 數據,使用時需將數據類型設置爲 JSONP。使用 JSONP 形式調用函數時,如 「myurl?callback=?」 jQuery 將自動替換 ? 爲正確的函數名,以執行回調函數。數據類型設置爲 「jsonp」 時,jQuery 將自動調用回調函數。

五、Ajax相關函數.

jQuery提供了一些相關函數可以輔助Ajax函數.

1. jQuery.ajaxSetup( options )
無返回值

說明:

  • 設置全局 AJAX 默認options選項。

講解:

有時咱們的但願設置頁面上全部Ajax屬性的默認行爲.那麼就可使用此函數設置options選項, 此後全部的Ajax請求的默認options將被更改.

好比,設置 AJAX 請求默認地址爲 「/xmlhttp/」,禁止觸發全局 AJAX 事件,用 POST 代替默認 GET 方法。其後的 AJAX 請求再也不設置任何選項參數:

$.ajaxSetup({ url: "/xmlhttp/", global: false, type: "POST" });
$.ajax({ data: myData });

2. serialize( )

Returns: String

說明:

  • 序列表表格內容爲字符串,用於 Ajax 請求。
  • 序列化最經常使用在將表單數據發送到服務器端時. 被序列化後的數據是標準格式, 能夠被幾乎全部的而服務器端支持.
  • 爲了儘量正常工做, 要求被序列化的表單字段都有name屬性, 只有一個eid是沒法工做的.

像這樣寫name屬性:

<input id="email" name="email" type="text" />

講解:

serialize()函數將要發送給服務器的form中的表單對象拼接成一個字符串. 便於咱們使用Ajax發送時獲取表單數據. 這和一個From按照Get方式提交時, 自動將表單對象的名/值放到url上提交差很少.
好比這樣一個表單:

這裏寫圖片描述

生成的字符串爲:single=Single&param=Multiple&param=Multiple3&check=check2&radio=radio1

3. serializeArray( )

Returns: Array<Object>

說明:

  • 序列化表格元素 (相似 ‘.serialize()’ 方法) 返回 JSON 數據結構數據。
  • 注意,此方法返回的是JSON對象而非JSON字符串。須要使用插件或者第三方庫進行字符串化操做。

講解:

看說明文檔讓我有所失望, 使用此函數獲取到的是JSON對象, 可是jQuery中沒有提供將JSON對象轉化爲JSON字符串的方法.
在JSON官網上沒有找到合適的JSON編譯器, 最後選用了jquery.json這個jQuery插件:
http://code.google.com/p/jquery-json/

使用起來異常簡單:

var thing = {plugin: 'jquery-json', version: 1.3};
var encoded = $.toJSON(thing);              //'{"plugin": "jquery-json", "version": 1.3}'
var name = $.evalJSON(encoded).plugin;      //"jquery-json"
var version = $.evalJSON(encoded).version;  // 1.3

使用serializeArray( ) 再配合 $.toJSON 方法, 咱們能夠很方便的獲取表單對象的JSON, 而且轉換爲JSON字符串:

$("#results").html( $.toJSON( $("form").serializeArray() ));

結果爲:

[{"name": "single", "value": "Single"}, {"name": "param", "value": "Multiple"}, {"name": "param" , "value": "Multiple3"}, {"name": "check", "value": "check2"}, {"name": "radio", "value": "radio1"}]

六、全局Ajax事件

在jQuery.ajaxSetup( options ) 中的options參數屬性中, 有一個global屬性:global 值類型:布爾值, 默認值: true,

說明:
是否觸發全局的Ajax事件.
這個屬性用來設置是否觸發全局的Ajax事件. 全局Ajax事件是一系列伴隨Ajax請求發生的事件.主要有以下事件:

第一列 第二列
ajaxComplete( callback ) AJAX 請求完成時執行函數
ajaxError( callback ) AJAX 請求發生錯誤時執行函數
ajaxSend( callback ) AJAX請求發送前執行函數
ajaxStart( callback ) AJAX請求開始時執行函數
ajaxStop( callback ) AJAX請求結束時執行函數
ajaxSuccess( callback ) AJAX 請求成功時執行函數

用一個示例講解各個事件的觸發順序:

<html >
<head>
    <title>jQuery Ajax - AjaxEvent</title>

    <script type="text/javascript" src="../scripts/jquery-1.3.2.min.js"></script>

    <script type="text/javascript"> $(document).ready(function() { $("#btnAjax").bind("click", function(event) { $.get("../data/AjaxGetMethod.aspx"); }) $("#divResult").ajaxComplete(function(evt, request, settings) { $(this).append('<div> ajaxComplete</div>'); }) $("#divResult").ajaxError(function(evt, request, settings) { $(this).append('<div> ajaxError</div>'); }) $("#divResult").ajaxSend(function(evt, request, settings) { $(this).append('<div> ajaxSend</div>'); }) $("#divResult").ajaxStart(function() { $(this).append('<div>ajaxStart</div>'); }) $("#divResult").ajaxStop(function() { $(this).append('<div>ajaxStop</div>'); }) $("#divResult").ajaxSuccess(function(evt, request, settings) { $(this).append('<div> ajaxSuccess</div>'); }) }); </script>

</head>
<body>    
  <br /><button id="btnAjax">發送Ajax請求</button><br/>
  <div id="divResult"></div>
</body>
</html>

結果如圖:

這裏寫圖片描述

咱們能夠經過將默認options的global屬性設置爲false來取消全局Ajax事件的觸發.

7. 注意事項

  1. 若是在Get請求發送的url中有兩個同名參數, 好比兩個param參數:
    http://localhost/AjaxGetMethod.aspx?param=Multiple&param=Multiple3
    使用服務器端方法獲取param參數:
if (!String.IsNullOrEmpty(HttpContext.Current.Request["Param"]))
        {
            param = HttpContext.Current.Request["Param"];
        }

此時獲取到得param是一個用」,」分隔多個值的字符串:
Multiple,Multiple3

8. 總結

本文介紹如何使用jquery實現Ajax功能. 用於發送Ajax請求的相關函數如load, get, getJSON和post這些漸變Ajax方法, 對於核心的ajax 方法沒有過多介紹, 主要是經過配置複雜的參數實現徹底控制Ajax請求. 另外講解了ajax的輔助函數好比用於序列化表單對象爲字符串的serialize()方法, 用於將表單對象序列化爲JSON對象的serializeArray()方法. 這些在使用腳本獲取數據實現與服務器端交互是頗有用, JSON格式的數據在處理大對象編程時將咱們從混亂的屬性字符串中解放出來.

jQuery還提供錄入全局ajax事件這一個特殊的事件, 而且能夠在一個對象上設置這些事件, 在發送Ajax請求的各個生命週期上會調用這些事件, 能夠經過修改默認的options對象的global屬性打開或關閉全局事件.

相關文章
相關標籤/搜索