首先祭上兩篇參考文獻
XHR對象實例所有的配置、屬性堕伪、方法揖庄、回調(diào)和不可變值
使用promise手動封裝ajax函數(shù)
上代碼:
// 使用promise實現(xiàn)一個簡單的ajax
/**
* 首先,可能會使用到的xhr方法或者說屬性
* onloadstart // 開始發(fā)送時觸發(fā)
* onloadend // 發(fā)送結(jié)束時觸發(fā)欠雌,無論成功不成功
* onload // 得到響應(yīng)
* onprogress // 從服務(wù)器上下載數(shù)據(jù)蹄梢,每50ms觸發(fā)一次
* onuploadprogress // 上傳到服務(wù)器的回調(diào)
* onerror // 請求錯誤時觸發(fā)
* onabort // 調(diào)用abort時候觸發(fā)
* status // 返回狀態(tài)碼
* setRequestHeader // 設(shè)置請求頭
* responseType // 請求傳入的數(shù)據(jù)
*/
// 默認的ajax參數(shù)
let ajaxDefaultOptions = {
url: '#', // 請求地址,默認為空
method: 'GET', // 請求方式富俄,默認為GET請求
async: true, // 請求同步還是異步禁炒,默認異步
timeout: 0, // 請求的超時時間
dataType: 'text', // 請求的數(shù)據(jù)格式,默認為text
data: null, // 請求的參數(shù)霍比,默認為空
headers: {}, // 請求頭幕袱,默認為空
onprogress: function () {}, // 從服務(wù)器下載數(shù)據(jù)的回調(diào)
onuploadprogress: function () {}, // 處理上傳文件到服務(wù)器的回調(diào)
xhr: null // 允許函數(shù)外部創(chuàng)建xhr傳入,但是必須不能是使用過的
};
function _ajax(paramOptions) {
let options = {};
for (const key in ajaxDefaultOptions) {
options[key] = ajaxDefaultOptions[key];
}
// 如果傳入的是否異步與默認值相同悠瞬,就使用默認值们豌,否則使用傳入的參數(shù)
options.async = paramOptions.async === ajaxDefaultOptions.async ? ajaxDefaultOptions.async : paramOptions.async;
// 判斷傳入的method是否為GET或者POST,否則傳入GET 或者可將判斷寫在promise內(nèi)部,reject出去
options.method = paramOptions.method ? ("GET" || "POST") : "GET";
// 如果外部傳入xhr浅妆,否則創(chuàng)建一個
let xhr = options.xhr || new XMLHttpRequest();
// return promise對象
return new Promise(function (resolve, reject) {
xhr.open(options.method, options.url, options.async);
xhr.timeout = options.timeout;
// 設(shè)置請求頭
for (const key in options.headers) {
xhr.setRequestHeader(key, options.headers[key]);
}
// 注冊xhr對象事件
xhr.responseType = options.dataType;
xhr.onprogress = options.onprogress;
xhr.onuploadprogress = options.onuploadprogress;
// 開始注冊事件
// 請求成功
xhr.onloadend = function () {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
resolve(xhr);
} else {
reject({
errorType: "status_error",
xhr: xhr
});
}
};
// 請求超時
xhr.ontimeout = function () {
reject({
errorType: "timeout_error",
xhr: xhr
});
}
// 請求錯誤
xhr.onerror = function () {
reject({
errorType: "onerror",
xhr: xhr
});
}
// abort錯誤(未明白望迎,只知道是三種異常中的一種)
xhr.onabort = function () {
reject({
errorType: "onabort",
xhr: xhr
});
}
// 捕獲異常
try {
xhr.send(options.data);
} catch (error) {
reject({
errorType: "send_error",
error: error
});
}
});
}
// 調(diào)用示例
_ajax({
url: 'http://localhost:3000/suc',
async: true,
onprogress: function (evt) {
console.log(evt.position / evt.total);
},
dataType: 'text/json'
}).then(
function (xhr) {
console.log(xhr.response);
},
function (e) {
console.log(JSON.stringify(e))
});
關(guān)于xhr的知識拓展:
你真的會使用XMLHttpRequest嗎?