1. 程式人生 > >Ajax瘋狂講義

Ajax瘋狂講義

ext 狀態信息 color 變化 intro 存在 統一 字符 UC

Ajax: async javascript and xml 異步的JS和XML

AJAX 是一種用於創建快速動態網頁的技術。 通過在後臺與服務器進行少量數據交換,AJAX 可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。傳統的網頁(不使用 AJAX)如果需要更新內容,必需重載整個網頁面。

Ajax創建四步法

我們都知道一個完整的Ajax動態網頁的實現方法為:

var xhr = new XMLHttpRequest;
xhr.open("get","url",true);
xhr.onreasystatechange = function () {
    
"code gose there"; } xhr.send(string);

下面我們就詳細的解釋一下上述的四個步驟。

AJAX - 創建一個Ajax XMLHttpRequest 對象


XMLHttpRequest 是 AJAX 的基礎。

XmlHttpRequest 術語縮寫為XHR,中文可以解釋為可擴展超文本傳輸請求。

所有現代瀏覽器(IE7+、Firefox、Chrome、Safari 以及 Opera)均內建 XMLHttpRequest 對象。(IE5 和 IE6 使用 ActiveXObject)。

XMLHttpRequest 用於在後臺與服務器交換數據。這意味著可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。

為了應對所有的現代瀏覽器,包括 IE5 和 IE6,請檢查瀏覽器是否支持 XMLHttpRequest 對象。如果支持,則創建 XMLHttpRequest 對象。如果不支持,則創建 ActiveXObject ::

function createXHR() {
        var xhr = null;
        if (window.XMLHttpRequest) {
            xhr = new XMLHttpRequest;
        } else {
            try {
                xhr = new ActiveXobject("Microsoft.XMLHTTP");
            } 
catch (e) { try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { } } } return xhr; }
var xhr = createXHR();

知上面的createXHR()方法每創建一個xhr對象,都會把createXHR方法執行一遍。由於我們第一次執行的時候就已經知道該瀏覽器下支持哪個new方法。但是第二次執行createXHR方法的時候就仍需要再全部重新執行一遍。這顯然會增加系統的開銷。所以我們可以用惰性思想的編程方式把支持瀏覽器的那個new方法返回來,這樣就不需要每次執行時都把全部的代碼執行一遍。

優化代碼代碼如下:

function createXHR() {
            var xhr = null,
                flag = false,
                arr = [
                    function () {
                        return new XMLHttpRequest;
                    },
                    function () {
                        return new ActiveXObject("Microsoft.XMLHTTP");
                    },
                    function () {
                        return new ActiveXObject("Msxm12.XMLHTTP");
                    }
                ];
            for (var i = 0; i < arr.length; i++) {
                var curFn = arr[i];
                try {
                    xhr = curFn();
                    //本次循環獲取的方法沒有出現錯誤:說明此方法是我想要的,我們下一次直接執行這個方法即可,,這就需要我把createXHR重寫為本次循環得到的方法(完成後不需要再判斷下面的,直接退出循環即可)
                    createXHR = curFn;
                    flag = true;
                    break;
                } catch (e) {
                    //本次循環獲取的方法執行時出現錯誤:繼續執行下一次循環
                }
                if (!flag) {
                    throw new Error("your browser is not support ajax,please change your browser,try again!");
                }
                
            }
            return xhr;
        }
var xhr = createXHR();

AJAX - 向服務器發送請求

XMLHttpRequest 對象用於和服務器交換數據。

當你的頁面全部加載完畢後,客戶端會通過 XMLHttpRequest 對象向服務器請求數據,服務器端接受數據並處理後,向客戶端反饋數據。

如需將請求發送到服務器,我們使用 XMLHttpRequest 對象的 open() 和 send() 方法:

xhr.open(method,url,async);
xhr.send(string);
  • 規定請求的類型、URL 以及是否異步處理請求。

    open(method,url,async)

      method:請求的類型;GET 或 POST

      url:文件在服務器上的位置,該文件可以是任何類型的文件

      async:true(異步)或 false(同步)

  • XMLHttpRequest 對象如果要用於 AJAX 的話,其 open() 方法的 async 參數必須設置為 true。因為當設置成false(即同步)時,JavaScript 會等到服務器響應就緒才繼續執行。如果服務器繁忙或緩慢,應用程序會掛起或停止。

   設置為true後,JavaScript 無需等待服務器的響應,而是:

    在等待服務器響應時執行其他腳本。

    當響應就緒後對響應進行處理。

  • send(string)

    將請求發送到服務器。

    string:僅用於 POST 請求,send方法也可以不傳參數,不傳參數的話,表示不向服務器發送請求數據

AJAX - 服務器響應

由於 HTTP 響應是由服務端發出的,並且服務器做出響應需要時間(比如網速慢等原因),所以我們需要監聽服務器響應的狀態,然後才能進行處理。 獲取來自服務器的響應,使用 XMLHttpRequest 對象的 responseText 或 responseXML 屬性。   - xhr.responseText屬性是獲取字符串形式的響應數據   - xhr.responseXML屬性是獲取XML形式的響應數據

AJAX - onreadystatechange 事件

當發送一個請求後,客戶端需要確定這個請求什麽時候會完成,因此,XMLHttpRequest對象提供了 onreadystatechange 事件機制來捕獲請求的狀態,繼而實現響應。

當請求被發送到服務器時,我們需要執行一些基於響應的任務。每當 readyState改變時,就會觸發 onreadystatechange 事件。readyState 屬性存有 XMLHttpRequest 的狀態信息。

下面是 XMLHttpRequest 對象的三個重要的屬性:

  • xhr.onreadystatechange

    存儲函數(或函數名),每當 readyState 屬性改變時,就會調用該函數。onreadystatechange  

  • xhr.readyState      

    存有 XMLHttpRequest 的狀態。從 0 到 4 發生變化。

      0:UNSET             請求未初始化,還沒有調用open()。

      1:OPENED            請求已經建立,但是還沒有發送,open()已被調用,還沒有調用send()。

      2:HEADER_RECEIVED      請求已發送,已經調用send()函數。正在處理中(通常現在可以從響應中獲取內容頭)。

      3:LOADING           請求在處理中;通常響應中已有部分數據可用了,沒有全部完成。

      4:LOADED            響應已完成;響應主體的內容已經成功返回到客戶端(解析完成)

  • xhr.status:HTTP狀態碼,描述了服務器響應內容的狀態

      200   OK /^2\d{2}/ (200或2開頭的數字) 都代表響應主體的內容已經成功返回了


      301   永久重定向/永久轉移
      302   臨時重定向/臨時轉移
      304   本次獲取的內容是讀取緩存中的數據


      400   客戶端傳遞給服務器的參數出現錯誤
      401   無權限訪問
      404   客戶端訪問的地址不存在

      500   未知的服務器錯誤
      503   服務器已經超出負荷

  當 readyState 等於 4 且狀態為 200 時,表示響應已就緒:在 onreadystatechange 事件中,我們規定當服務器響應已做好被處理的準備時所執行的任務。

編寫一個簡易的Ajax方法庫

由於每次編寫Ajax方法都需要寫下上面完整的Ajax四步,這無疑增加了我們的工作量。下面我們來編寫一個一個Ajax方法,我們只需要調用這個方法就可以實現Ajax的XMLHttpRequest請求。

//ajax:實現AJAX請求的公共方法:當一個方法傳遞的參數值過多,而且不固定,我們使用對象統一傳值法(需把要傳遞的參數值都先放在一個對象options中,一起傳遞進去即可)
    function ajax(options) {
        var _default = {
            url : "", //請求的地址
            type : "get",    //請求的方式
            dataType : "json",    //設置請求回來的內容格式"json"(即json格式的對象)。"txt"就是字符串或json格式的字符串
            async : true,    //請求是同步還是異步
            data : null,    //放在請求主體中的內容(POST)
            getHeaders : null,    //當READYSTATE===2時執行的回調函數
            success : null    //當readystate===4時執行的回調函數
        }
        for (var key in options) {
            if (options.hasOwnProperty(key)) {
                _default[key] = options[key];
            }
        }
        //如果當前的請求方式是GET,我們需要在URL的末尾添加隨機數清除緩存
        if (_default[type] === "get") {
            _deauult[url].indexOf("?") >= 0 ? _default[url] += "&" :_default[url] += "?";
            _default[url] += "_=" + Math.random(); 
        }
        var xhr = createXHR();
        xhr.open(_default[type],_default[url],_default[async]);
        xhr.onreadystatechange = function () {
            if (/^2\d{2}$/.test(xhr.status)) {
                //想要在readystate=2的時候做一些操作,需要保證ajax是異步請求
                if (xhr.readyState === 2) {
                    if (typeof(_default[getHeaders]) === "function") {
                        _default[getHeaders].call(xhr);
                    }
                    
                }
                if (xhr.readyState == 4) {
                    var val = xhr.responseText;
                    if (_default.dataType === "json") {
                        val = "JSON" in window ? JSON.parse(val) : eval("(" + val + ")");
                    }
                    if (typeof(_default[success]) === "function") {
                        _default[success].call(xhr,val);
                    };//_default[success] && _default[success].call(xhr,val);
                    
                }
            }
        }
        xhr.send(_default[data]);//向請求主體傳內容,但open方法中必須使用post請求方式
    }

Ajax瘋狂講義