一點對原生HTTP請求的理解與總結


全手打原創,轉載請標明出處:https://www.cnblogs.com/dreamsqin/p/10946165.html,多謝,=。=~

 

術語

HTTP:超文本傳輸協議,規定Web瀏覽器如何從Web服務器獲取文檔和向Web服務器提交表單內容,以及Web服務器如何響應這些請求和提交;

(HTTP不在腳本控制下,只當用戶點擊鏈接、提交表單、輸入URL時發生。但是js可操縱HTTP,例如設置window對象的location屬性、調用表單的submit()方法會初始化HTTP請求,頁面會重新加載。)

Ajax:使用腳本操縱HTTP的Web應用架構,實現與Web服務器的數據交換,不會導致頁面重載,客戶端從服務器“拉”數據,可利用XMLHttpRequest對象實現;

Comet:使用腳本操縱HTTP的Web應用架構,與Ajax相反,服務器向客戶端“推”數據,可利用EventSource對象實現;

XMLHttpRequest:定義了用腳本操縱HTTP的API;

(XMLHttpRequest對象支持包括XML在內的任何基於文本的格式,能用於HTTP和HTTPS請求,涉及HTTP請求或響應的所有活動)

 

XMLHttpRequest的使用

實例化(IE7及以后):

var request = new XMLHttpRequest();

模擬XMLHttpRequest構造函數(IE5、IE6):

if (window.XMLHttpRequest === undefined) {
    window.XMLHttpRequest = function() {
        try {
            return new ActiveXObject("MSXML2.XMLHttp.6.0");
        }
        catch (e1) {
            try {
                return new ActiveXObject("MSXML2.XMLHttp.3.0");
            }
            catch (e2) {
                throw new Error("XMLHttpRequest is not supported");
            }
        }
    }
}

HTTP請求(請求的方法或動作、請求的URL、請求頭、請求體):

request.open("GET", "/log.php");    // 請求的方法、URL
request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");   // 請求頭
request.send(null);   // 請求體

HTTP響應(數字+文字的狀態碼、響應頭、響應體):

request.onreadystatechange = function() {
    // HTTP的請求狀態readyState
    // 0:open尚未調用
    // 1:open已調用
    // 2:接收到頭信息
    // 3:接收到響應主體
    // 4:響應完成
    
    // HTTP狀態碼status
    // 2xx:代表請求已成功被服務器接收、理解、並接受
    if(request.readyState === 4 && request.status === 200) {
        // responseText屬性:MIME類型的文本響應,如:text/css
        // responseXML屬性:Document對象類型,如:XML、XHTML
        console.log(request.responseText);
    }
};

 響應解碼

request.onreadystatechange = function() {
    if (request.readyState === 4 && request.status === 200) {
        var type = request.getResponseHeader("Content-type");
        if (type.indexOf("xml") !== -1 && request.responseXML) {
            console.log(request.responseXML);   // Document對象響應
        } else if (type === "application/json"){
            console.log(JSON.parse(request.responseText));   // Json響應
        } else {
            console.log(request.responseText);   // 字符串響應
        }
    }
};

 

請求主體編碼(POST請求)

1、表單編碼(對名字和值進行URL編碼(即使用十六進制轉義碼替換特殊字符)、使用=分開編碼后的名字和值、使用&連接名/值對)

PS:<input type="submit">定義用於向表單處理程序(form-handler)提交表單的按鈕,自帶表單編碼功能。

POST請求必須設置請求頭:

request.open("POST",url);
request.setRequestHeader("Content-type","application/x-www-form-urlencoded"); request.send(encodeFormData(data));

 GET請求只需跟在url連接后即可:

request.open("GET", url + "?" + encodeFormData(data));
request.send(null);

表單編碼函數encodeFormData:

// 對象屬性的表單編碼
function encodeFormData(data) {
    if (!data) return "";   // 如果data非對象則返回空字符串
    var paris = [];   // 保存名=值對
    for(var name in data) {
        if (!data.hasOwnProperty(name)) continue;   // 跳過繼承屬性
        if (typeof data[name] === "function") continue;   // 跳過方法
        var value = data[name].toString();   // 將值轉換為字符串
        name = encodeURIComponent(name.replace("20%", "+"));   // 編碼名字
        value = encodeURIComponent(value.replace("20%", "+"));   // 編碼值
        paris.push(name + "=" +value);
    }
    return paris.join("&");   // 使用"&"連接名/值對
}

2、JSON編碼(使用JSON.stringify()方法)

request.open("POST",url);
request.setRequestHeader("Content-type","application/json");
request.send(JSON.stringify(data));

3、XML編碼(send方法中傳遞XML Document對象)

<query>
    <find zipcode="02134" radius="1km">
        pizza
    </find>
</query>
function createXML(what, where, radius) {
    // Create an XML document with root element <query>
    var doc = document.implementation.createDocument("", "query", null);
    var query = doc.documentElement;   // <query>元素
    var find = doc.createElement("find");   // 創建<find>元素
    query.appendChild(find);   // 把<find>添加至<query>中
    find.setAttribute("zipcode", where);   // 設置<find>的屬性
    find.setAttribute("radius", radius);
    find.appendChild(doc.createTextNode(what));   // 設置<find>的內容
    return doc;
}

// 會自動設置Content-type頭
request.send(createXML("pizza", "02134", "1km"));

4、文件上傳

 HTML表單<input type="file">始終能上傳文件;XMLHTTPRequest無法實現;XHR2可以通過向send()方法傳入File對象實現(文件類型是更通用的二進制大對象Blob類型中的一個子類型)。

5、multipart/form-data請求

當HTML表單同時包含文件上傳元素和其他元素時,必須使用Content-type為multipart/form-data的特殊方式提交表單,該編碼使用長“邊界”字符串把請求主體分離成多個部分。

XHR2定義了新的FormData API,容易實現多部分請求主體(使用FormData()構造函數創建FormData對象,然后按需多次調用這個對象的append()方法把個體的“部分”(字符串、File或Blob對象)添加到請求中)。

function createFormData(data) {
    if (typeof FormData === "undefined") {
        throw new Error("FormData is not implemented");
    }
    var formData = new FormData();
    for(var name in data) {
        if (!data.hasOwnProperty(name)) continue;
        var value = data[name];
        if (typeof value === "function") continue;
        formData.append(name, value);
    }
    return formData;
}

request.send(createFormData({user: "aaa", text: "bbb"}));

 

HTTP請求無法完成的3種情況

1、timeout事件:請求超時;

2、abort事件:請求中止;

3、error事件:比如太多重定向這樣的網絡錯誤會阻止請求完成;


免責聲明!

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



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