写在前面
fetch
同XMLHttpRequest
非常类似,都是用来做网络请求。但是同复杂的XMLHttpRequest
的API
相比,fetch
提供了更加强大灵活的特性,使用了Promise
,这让它使用起来更加简洁,从而避免陷入”回调地狱”。
与XMLHttpRequest的比较
使用XMLHttpRequest
来实现改功能需要设置两个监听函数,分别用来处理成功和失败的情况,同时还需要依次调用open()
和send()
方法才能实现请求。
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来实现是这样的:
fetch('./api/some.json')
.then(function(res) {
if (res.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' + res.status); return;
}
// 处理响应中的文本信息
res.json().then(function(data) {
console.log(data);
});
})
.catch(function(err) {
console.log('Fetch Error : %S', err);
})
为什么要代替XMLHttpRequest
看了前面的例子,你可能会问,为什么不直接使用那些[现有的XMLHttpRequest
包装器]呢? 原因在于Fetch API
不仅仅为你提供了一个fetch()
方法。
你可以通过Request
构造器函数创建一个新的请求对象,这也是建议标准的一部分。 第一个参数是请求的URL
,第二个参数是一个选项对象,用于配置请求。请求对象一旦创建了, 你便可以将所创建的对象传递给fetch()
方法,用于替代默认的URL字符串。
每个Request
对象都有一个header
属性,在Fetch API
中它对应了一个Headers
对象。 通过Headers
对象,你能够修改请求头。不仅如此,对于返回的响应,你还能轻松的返回响应头中的各个属性。 但是需要注意的是,响应头是只读的。
响应中的元数据
在上面的例子中,我们可以查看响应对象的状态码,也知道了如何将响应转换成JSON格式的数据。但其实我们可以访问的元数据还有以下这些:
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
的使用场景。例如, 使用标准的ES6 Promise
你无法收集进入信息或中断请求。但另一方面,使用XMLHttpRequest
你可以模拟进度(监听progress
事件),也可以取消请求(使用abort()
方法)。但是,如果有必要你也可以使用Promise
来包裹它
浏览器支持
demo
本人在实际项目用到的封装好的方法,仅供参考
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;
}
// 处理响应中的文本信息
return res.json();
}).catch(function(err) {
console.log('Fetch Error : %S', err);
})
}