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

全手打原創,轉載請標明出處:http://www.javashuo.com/article/p-ntbwarcp-be.html,多謝,=。=~php

 

術語css

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

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

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

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

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

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

 

XMLHttpRequest的使用app

實例化(IE7及之後):函數

var request = new XMLHttpRequest();

模擬XMLHttpRequest構造函數(IE五、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請求)

一、表單編碼(對名字和值進行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("&");   // 使用"&"鏈接名/值對
}

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

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

三、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"));

四、文件上傳

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

五、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種狀況

一、timeout事件:請求超時;

二、abort事件:請求停止;

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

相關文章
相關標籤/搜索