原生ajax解析&封裝原生ajax函數

  前沿:對於此篇隨筆,完是簡要寫了幾個重要的地方,具體實現細節完在提供的源碼作了筆記ajax

<一>ajax基本要點介紹--更好的介紹ajaxsegmentfault

1. ajax對象中new XMLHttpRequest()屬性和方法列表瀏覽器

2. 經常使用事件介紹服務器

事件 觸發時機
onreadystatechange 當readyState的值改變時觸發,除了當它從非0變成0時
onloadstart 當調用send方法時會觸發xhr.onloadstart,而後會觸發xhr.upload.onloadstart,表明開始上傳數據
onprogress 上傳數據過程當中會觸發xhr.upload.onprogress,下載數據過程當中會觸發xhr.onprogress,onprogress每50ms會觸發一次
onabort 調用abort方法後會觸發
onerror 當發生網絡異常的時候會觸發,若是上傳數據的過程還未結束,此時會先觸發xhr.upload.onerror,而後再觸發xhr.onerror;若是上傳數據的過程已經結束,此時只會觸發xhr.onerror
onload 上傳數據成功,會觸發xhr.upload.onload;下載數據成功會觸發xhr.onload
ontimeout 當服務端響應的時間超過指定的timeout時間時,會觸發此事件
onloadend 上傳數據完成(成功或者失敗)時會觸發xhr.upload.onloadend;下載數據完成(成功或失敗)會觸發

3. 請求開始和結束零界點網絡

【3.1】請求開始app

  xhr.onloadstart事件觸發的時候,也就是你調用xhr.send()方法的時候。
由於xhr.open()只是建立了一個鏈接,但並無真正開始數據的傳輸,而xhr.send()纔是真正開始了數據的傳輸過程。只有調用了xhr.send(),纔會觸發xhr.onloadstart 。異步

【3.2】請求結束ide

  xhr.loadend事件觸發的時候函數

備註:post

  a.能夠在 send()以後再設置此xhr.timeout,但計時起始點仍爲調用xhr.send()方法的時刻。

  b.當xhr爲一個sync同步請求時,xhr.timeout必須置爲0,不然會拋錯。緣由能夠參考本文的【如何發一個同步請求】一節。

4. 具體實現細節--封裝ajax

function _ajax(obj){
    var xhr = null;
    // 建立-非IE6 : IE6及其如下瀏覽器
    if(window.XMLHttpRequest){
        xhr=new XMLHttpRequest();
        //針對某些特定版本的Mozillar瀏覽器的BUG進行修正
        if(xhr.overrideMimeType) {
            xhr.overrideMimeType("text/xml");
        }
    }else if(window.ActiveXObject){
        var arr = ['MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
        for(var i = 0; i < arr.length; i++){
            try {
                xhr = new ActiveXObject(arr[i]);
                break;
            }catch (e){
                console.log(e);
            }
        }
    }

    // 默認是異步請求
    var asyc = obj.asyc || true;
    var type = obj.type.toUpperCase() || "GET";
    var url = obj.url;
    var data = obj.data || {};

    console.log(objToStr(data));

    //選擇發送請求方式
    if(type === "GET"){
        xhr.open(type,url+'?'+objToStr(data),asyc);
        xhr.send();
    }else if(type === "POST"){
        xhr.open(type,url,asyc);
        // 告訴後臺傳的是什麼
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        // xhr.setRequestHeader('Last-Modified', 'faqenfaAWASVaewfc');
        xhr.send(objToStr(data));
    }

    // 設置超時請求時間
    xhr.timeout = 3000;

    // 發送異步回調函數
    xhr.onreadystatechange = function () {
        console.log(xhr.readyState);
        // 測試追蹤ajax處於那種狀態,在正式代碼中要隱藏此switch
        switch (xhr.readyState){
            case 0:
                console.log('xhr對象被成功構造,open()方法還未被調用');
                break;
            case 1:
                console.log('open()方法已被成功調用,send()方法還未被調用');
                break;
            case 2:
                console.log('send()方法已經被調用, 響應頭和響應狀態已經返回');
                break;
            case 3:
                console.log('響應體(response entity body)正在下載中,此狀態下經過xhr.response可能已經有了響應數據');
                break;
            case 4:
                console.log('整個數據傳輸過程結束,無論本次請求是成功仍是失敗');
                break;
        }

        if(xhr.readyState === 4 && xhr.status === 200){
            obj.success(xhr.responseText)
        }else {
            obj.error && obj.error();
        }
    };

    // 請求開始
    xhr.onloadstart = function (e) {
        console.log(e,'start');
    };

    //ajax請求結束
    xhr.loadend = function (e) {
        console.log(e,'end');
    };

    // 超時函數處理
    xhr.ontimeout = function (e) {
        obj.timeout && obj.timeout();
        console.log(e,'timeout');
    };

    // ajax請求錯誤處理
    xhr.onerror = function (e) {
        obj.errorAsyc && obj.errorAsyc();
        console.log(e,'error');
    };

    // 上傳進度處理--upload用於在數據傳輸到服務器時收集一些傳輸信息,好比上傳了多少字節,總共多少字節等,其裏面還包含了一些事件回調
    xhr.upload.onprogress = function (e) {
        obj.progress && obj.progress();
        console.log(e,'progress');
    };

    console.log(xhr.getAllResponseHeaders(),'0000');
    // 把對象轉換成字符串
    function objToStr(obj) {
        var arr = [];
        for(var key in obj){
            arr.push(key+'='+obj[key])
        }
        return arr.join('&');
    }
}

【封裝ajax調用方式】

   window.onload = function () {
        btn.onclick= function () {
            _ajax({
                url:'http://localhost:8800',
                type:'post',
                asyc:true, //默認是true
                data:{
                    username:'zhange',
                    password:'123456'
                },
                success:function (data) {
                    console.log(data);
                },
                error:function () {

                }
            });
        }
    };
相關文章
相關標籤/搜索