寫在前面
fetch
同XMLHttpRequest
非常類似,都是用來做網(wǎng)絡(luò)請(qǐng)求懂鸵。但是同復(fù)雜的XMLHttpRequest
的API
相比财著,fetch
提供了更加強(qiáng)大靈活的特性,使用了Promise
认罩,這讓它使用起來更加簡潔,從而避免陷入”回調(diào)地獄”。
與XMLHttpRequest的比較
使用XMLHttpRequest
來實(shí)現(xiàn)改功能需要設(shè)置兩個(gè)監(jiān)聽函數(shù)澎胡,分別用來處理成功和失敗的情況,同時(shí)還需要依次調(diào)用open()
和send()
方法才能實(shí)現(xiàn)請(qǐng)求。
function reqListener() {
var data = JSON.parse(this.responseText); console.log(data);
}
function reqError(err) {
console.log('Fetch Error : %S', err);
}
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;oReq.open('get', './api/some.json', true);
oReq.send();
使用fetch來實(shí)現(xiàn)是這樣的:
fetch('./api/some.json')
.then(function(res) {
if (res.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + res.status); return;
}
// 處理響應(yīng)中的文本信息
res.json().then(function(data) {
console.log(data);
});
})
.catch(function(err) {
console.log('Fetch Error : %S', err);
})
為什么要代替XMLHttpRequest
看了前面的例子攻谁,你可能會(huì)問稚伍,為什么不直接使用那些[現(xiàn)有的XMLHttpRequest
包裝器]呢? 原因在于Fetch API
不僅僅為你提供了一個(gè)fetch()
方法戚宦。
你可以通過Request
構(gòu)造器函數(shù)創(chuàng)建一個(gè)新的請(qǐng)求對(duì)象个曙,這也是建議標(biāo)準(zhǔn)的一部分。 第一個(gè)參數(shù)是請(qǐng)求的URL
受楼,第二個(gè)參數(shù)是一個(gè)選項(xiàng)對(duì)象垦搬,用于配置請(qǐng)求。請(qǐng)求對(duì)象一旦創(chuàng)建了艳汽, 你便可以將所創(chuàng)建的對(duì)象傳遞給fetch()
方法猴贰,用于替代默認(rèn)的URL字符串。
每個(gè)Request
對(duì)象都有一個(gè)header
屬性河狐,在Fetch API
中它對(duì)應(yīng)了一個(gè)Headers
對(duì)象米绕。 通過Headers
對(duì)象,你能夠修改請(qǐng)求頭馋艺。不僅如此栅干,對(duì)于返回的響應(yīng),你還能輕松的返回響應(yīng)頭中的各個(gè)屬性丈钙。 但是需要注意的是非驮,響應(yīng)頭是只讀的。
響應(yīng)中的元數(shù)據(jù)
在上面的例子中雏赦,我們可以查看響應(yīng)對(duì)象的狀態(tài)碼劫笙,也知道了如何將響應(yīng)轉(zhuǎn)換成JSON格式的數(shù)據(jù)。但其實(shí)我們可以訪問的元數(shù)據(jù)還有以下這些:
fetch("some.json").then(function(res) {
console.log(res.headers.get('Content-Type'));
console.log(res.headers.get('Data'));
console.log(res.status);
console.log(res.statusText);
console.log(res.type);
console.log(res.url);
})
fetch不足之處
Promises
缺少了一些重要的XMLHttpRequest
的使用場景星岗。例如填大, 使用標(biāo)準(zhǔn)的ES6 Promise
你無法收集進(jìn)入信息或中斷請(qǐng)求。但另一方面俏橘,使用XMLHttpRequest
你可以模擬進(jìn)度(監(jiān)聽progress
事件)允华,也可以取消請(qǐng)求(使用abort()
方法)。但是寥掐,如果有必要你也可以使用Promise
來包裹它
瀏覽器支持
demo
本人在實(shí)際項(xiàng)目用到的封裝好的方法,僅供參考
function fetchPost(url ,data) {
let host = DIX.HOST + url;
let token = UTIL.getToken();
let dataUrl = '';
if (data) {
for (let item in data) {
if (data.hasOwnProperty(item)) {
dataUrl += ('&' + item + '=' + data[item]);
}
}
}
let body = 'client=1&version=3&token=' + token + dataUrl;
return fetch (host, {
method: 'POST',
headers: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: body
}).then(function(res) {
if (res.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + res.status);
return;
}
// 處理響應(yīng)中的文本信息
return res.json();
}).catch(function(err) {
console.log('Fetch Error : %S', err);
})
}