原生JS實現Ajax異步請求

原生JS實現Ajax請求

XMLHttpRequest對象

在IE7如下的瀏覽器,不支持原生XHR對象,須要使用MSXML庫中的XHR對象,有三種不一樣版本: MSXML2.XMLHttp、MSXML2.XMLHttp.3.0 和 MXSML2.XMLHttp.6.0。php

若是要兼容這些瀏覽器,必須建立一個函數來處理兼容問題。git

function createXHR(){
    if (typeof XMLHttpRequest != "undefined"){
        return new XMLHttpRequest();
    } else if (typeof ActiveXObject != "undefined"){
        if (typeof arguments.callee.activeXString != "string"){
            var versions = [ "MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"], i, len;
            for (i=0,len=versions.length; i < len; i++){
                try {
                    new ActiveXObject(versions[i]);
                    arguments.callee.activeXString = versions[i];
                    break;
                } catch (ex){
                    //跳過
                }
            }
        }
        return new ActiveXObject(arguments.callee.activeXString);
    } else {
        throw new Error("No XHR object available.");
    }
}

而後就能夠使用var xhr = createXHR();來在全部瀏覽器中建立XHR對象了。github

XHR的用法

get請求

使用XHR對象,要調用的第一個方法是open()方法,用來初始化請求,接受三個參數,分別是請求類型、請求URL、是否異步發送請求。
xhr.open("get", "demo.php", true);ajax

要發送get請求,必須接着調用send()方法:xhr.send(null);瀏覽器

因爲是異步請求,須要檢測一個狀態,等待數據接收完畢再處理請求。這個狀態經過readyState來表示。
readyState的值能夠取0/1/2/3/4,分別表明未初始化、啓動、發送、接受、完成狀態。每次readyState改變都會觸發事件: readystatechange
注意,爲了保證跨瀏覽器兼容性,須要在open方法以前指定 onreadystatechange 事件。服務器

var xhr = createXHR();
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4){
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
            alert(xhr.responseText);
        } else {
            alert("Request was unsuccessful: " + xhr.status);
        }
    }
};
xhr.open("get", 'demo.php', true);
xhr.send(null);

對於get請求URL的查詢字符串參數,能夠使用encodeURIComponent來將參數轉化爲合法的URL。併發

function addURLParam(url, name, value){
    url += (url.indexOf("?") == -1 ? "?" : "&");
    url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
    return url;
}

post請求

與get請求不一樣的是,post請求須要在send方法中,傳入數據參數。還須要設置http請求頭信息,將Content-Type設置爲application/x-www-form-urlencodedapp

function submitData(id){
    var xhr = createXHR();
    xhr.onreadystatechange = function(){
        if (xhr.readyState == 4){
            if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                alert(xhr.responseText);
            } else {
                alert("Request was unsuccessful: " + xhr.status);
            }
        }
    };
    xhr.open("post", "postexample.php", true);
    xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    var form = document.getElementById(id); // 將ID爲id的表單中的數據序列化後發送給服務器
    xhr.send(serialize(form)); // 將表單數據序列化併發送
}

serialize表單序列化函數:異步

function serialize(form){
    var parts = [],
    field = null,
    i,
    len,
    j,
    optLen,
    option,
    optValue;

    for (i=0, len=form.elements.length; i < len; i++){
        field = form.elements[i];

        switch(field.type){
            case "select-one":
            case "select-multiple":
            
            if (field.name.length){
                for (j=0, optLen = field.options.length; j < optLen; j++){ 
                    option = field.options[j];
                    if (option.selected){
                        optValue = "";
                        if (option.hasAttribute){
                            optValue = (option.hasAttribute("value") ? option.value : option.text);
                        } else {
                            optValue = (option.attributes["value"].specified ? option.value : option.text);
                        }
                        parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue));
                    }
                }
            }
            break;

            case undefined: //字段集
            case "file": //文件輸入
            case "submit": //提交按鈕
            case "reset": //重置按鈕
            case "button": //自定義按鈕
                break;

            case "radio": //單選按鈕
            case "checkbox": //複選框
                if (!field.checked){
                    break;
                }
                /* 執行默認操做 */
            default:
                //不包含沒有名字的表單字段
                if (field.name.length){
                    parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value));
                }
        }
    }
    return parts.join("&");
}

XMLHttpRequest進度事件

load: 在接收到完整的響應數據時觸發該事件。只支持IE8+以上的瀏覽器。函數

能夠用來替代readystatechange事件,響應接收完畢就觸發load事件,所以沒有必要去檢查readyState屬性了。

var xhr = createXHR();
xhr.onload = function(){
    if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
        alert(xhr.responseText);
    } else {
        alert("Request was unsuccessful:" + xhr.status);
    }
};
xhr.open("get", "demo.php", true);
xhr.send(null);

詳情請見筆記: JavaScript高級程序設計: Ajax

相關文章
相關標籤/搜索