jQuery ajax —— Baidu ajax


你沒有看錯標題,本文的確是在講Baidu ajax,不過是很久很久以前的版本了。

由於jQuery ajax模塊有800+行,而核心函數jQuery.ajax就有380+行,直接分析這段代碼很容易被代碼邏輯弄暈。

所以我們先分析一段簡單的ajax代碼,來自早期的百度七巧板項目。

通過這個來先復習一遍ajax的知識。

 

baidu.ajax.request分離版

 

/**
 * 發送一個ajax請求
 * @author: allstar, erik, berg
 * @name ajax.request
 * @function
 * @grammar ajax.request(url[, options])
 * @param {string}     url 發送請求的url
 * @param {Object}     options 發送請求的選項參數
 * @config {String}     [method]             請求發送的類型。默認為GET
 * @config {Boolean}  [async]             是否異步請求。默認為true(異步)
 * @config {String}     [data]                 需要發送的數據。如果是GET請求的話,不需要這個屬性
 * @config {Object}     [headers]             要設置的http request header
 * @config {number}   [timeout]       超時時間,單位ms
 * @config {String}     [username]             用戶名
 * @config {String}     [password]             密碼
 * @config {Function} [onsuccess]         請求成功時觸發,function(XMLHttpRequest xhr, string responseText)。
 * @config {Function} [onfailure]         請求失敗時觸發,function(XMLHttpRequest xhr)。
 * @config {Function} [onbeforerequest]    發送請求之前觸發,function(XMLHttpRequest xhr)。
 * 
 * @meta standard
 * @see ajax.get,ajax.post
 *             
 * @returns {XMLHttpRequest} 發送請求的XMLHttpRequest對象
 */
var ajax = {};
ajax.request = function(url,options,type){
        // 是否需要異步
    var async = options.async||true,
        // 用戶名、密碼
        username = options.username||"",
        password = options.password||"",
        // 需要傳輸的數據
        data = options.data||"",
        // GET還是POST
        method = (options.method||"GET").toUpperCase(),
        // 請求頭
        headers = options.headers||{},
        // 事件處理函數表
        eventHandler = {},
        // 請求數據類型
        dataType = type||"string";//xml||string
    
    function stateChangeHandler(){
        // 看看是否已經准備好了
        if(xhr.readyState == 4){
            // 得到xhr當前狀態
            var sta = xhr.status;
            // 判斷是否成功
            if(sta == 200||sta == 304){
                // 成功則觸發成功
                fire("success");
            }else{
                // 失敗則觸發失敗
                fire("failure");
            }
        
            // 清除綁定
            window.setTimeout(function(){
                xhr.onreadystatechange= new Function();
                if (async){
                    xhr = null;
                }
            },0);
        }
    }
    
    
    function fire(type){
        // 把type變成ontype
        type = "on"+type;
        // 在事件處理器表中找到對應事件的處理函數
        var handler = eventHandler[type];
        // 如果函數存在,則
        if(handler){
            // 不成功的話
            if(type != "onsuccess"){
                handler(xhr);
            // 成功了
            }else{
                // 則根據dataType返回不同的數據
                handler(xhr,dataType!="xml"?xhr.responseText:xhr.responseXML);
            }
        }
    }
    
    // 組裝eventHandler
    for(var key in options){
        eventHandler[key] = options[key];
    }
    
    // 新建一個XMLHttpRequest對象
    var xhr = new XMLHttpRequest();
    // 如果方法是GET,則把數據組裝到url中
    if(method == "GET"){
        url += (url.indexOf("?")>=0)?"&":"?";
        url += data;
        // 清空data
        data = null;
    }
    // 如果是異步
    if (async){
        // 綁定readystatechange的處理器
        xhr.onreadystatechange = stateChangeHandler;
    }
    // 看看是否需要輸入密碼
    if(username){
        xhr.open(method,url,async,username,passowrd);
    }else{
        xhr.open(method,url,async);
    }
    // 如果是POST
    if(method == "POST"){
        // 設置一下請求頭
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    }
    // 把options中的請求頭信息全部設置進去
    for(var key in headers){
        xhr.setRequestHeader(name,headers[key])
    }
    // 觸發事件beforerequest
    fire("beforerequest");
    // 發送數據
    xhr.send(data);
    
    // 如果不是異步
    if (!async){
        // 則直接運行stateChangeHandler來處理數據
        stateChangeHandler();
    }

    return xhr;
}

 

這段代碼還是比較容易理解的:

  • 通過XMLHttpRequest()新建一個XMLHttpRequest對象。
  • 看看是GET,還是POST方式,如果是GET則組裝url,如果是POST,設置一下請求頭。
  • 看看是不是異步,如果是則注冊監聽函數stateChangeHandler。
  • 看看需不需要用戶名和密碼,執行open。
  • 發送請求。
  • 等待監聽函數處理事件。

 

baidu.ajax.get & baidu.ajax.post

/**
 * 發送一個post請求
 * @name ajax.post
 * @function
 * @grammar ajax.post(url, data[, onsuccess])
 * @param {string}     url         發送請求的url地址
 * @param {string}     data         發送的數據
 * @param {Function} [onsuccess] 請求成功之后的回調函數,function(XMLHttpRequest xhr, string responseText)
 * @meta standard
 * @see ajax.get,ajax.request
 *             
 * @returns {XMLHttpRequest}     發送請求的XMLHttpRequest對象
 */
ajax.post = function(url,data,onsuccess){
    return ajax.request(url,{"data":data,"onsuccess":onsuccess,method:"POST"});
}
/**
 * 發送一個get請求
 * @name ajax.get
 * @function
 * @grammar ajax.get(url[, onsuccess])
 * @param {string}     url         發送請求的url地址
 * @param {Function} [onsuccess] 請求成功之后的回調函數,function(XMLHttpRequest xhr, string responseText)
 * @meta standard
 * @see ajax.post,ajax.request
 *             
 * @returns {XMLHttpRequest}     發送請求的XMLHttpRequest對象
 */
ajax.get = function(url,data,onsuccess){
    return ajax.request(url,{"data":data,"onsuccess":onsuccess});
}

baidu.ajax.get和baidu.ajax.post都是通過baidu.ajax.request擴展的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM