- Axios和fetch都提供HTTP请求的方法,本文对二者进行对比
-
兼容性
- Axios可以支持IE11,而fetch不支持IE,兼容性上稍差,但是可以通过引入polyfill解决该问题,而且fetch是浏览器内置的API,使用方便,在node端使用的话可以使用isomorphic-fetch库进行
// 安装polyfill的库 npm i whatwg-fetch --saveimport 'whatwg-fetch' window.fetch(...) -
请求的细节上
- Axios会自动将JSON对象进行stringify,而fetch里面需要手动做这一步,同样的对于返回值而言,Axios会直接返回JSON对象,而fetch里面则是需要额外进行response.json()的操作
// Axios的请求方式 const options = { url: 'someUrl.com', method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json;charset=UTF-8' }, // 数据写在data字段中 data: { name: 'Ryan', age: 24 } }; axios(options) .then(response => { console.log(response.status); return response.data; }) .then(data => { console.log(data) }); // fetch的请求方式 const url = 'someUrl.com'; const options = { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json;charset=UTF-8' }, // 数据写在body字段中,需要手动stringify body: JSON.stringify({ a: 10, b: 20 }) }; fetch(url, options) .then(response => { console.log(response.status); // 需要手动获得JSON对象 return response.json() }) .then(data => { console.log(data) }); -
HTTP的拦截
- Axios的一大feature就是提供了对请求的拦截以及响应的拦截,使得用户可以对请求参数或是返回结果进行统一的处理,fetch没有原生地提供该方法,但是可以通过全局改造fetch得到一个具有拦截作用的新fetch
axios.interceptors.request.use(config => { // log a message before any HTTP request is sent console.log('Request was sent'); return config; }); // sent a GET request axios.get('someUrl.com/users') .then(response => { console.log(response.data); }); // rewrite fetch fetch = (originalFetch => { return (...arguments) => { const result = originalFetch.apply(this, arguments); return result.then(console.log('Request was sent')); }; })(fetch); fetch('someUrl.com/users') .then(response => response.json()) .then(data => { console.log(data) }); -
请求超时处理
- Axios提供请求超时进行取消的选项,只需要在option中配置timeout字段即可,而fetch没有原生提供这项功能,但是可以通过AbortController对象来实现请求的abort
axios({ method: 'post', url: '/login', timeout: 4000, // 4 seconds timeout data: { firstName: 'David', lastName: 'Pollock' } }) .then(response => {/* handle the response */}) .catch(error => console.error('timeout exceeded')) const controller = new AbortController(); const options = { method: 'POST', signal: controller.signal, body: JSON.stringify({ firstName: 'David', lastName: 'Pollock' }) }; const promise = fetch('/login', options); // 利用AbortController对象的的abort方法像fetch请求发送signal,取消请求 const timeoutId = setTimeout(() => controller.abort(), 4000); promise .then(response => {/* handle the response */}) .catch(error => console.error('timeout exceeded')); -
多请求处理
- Axios提供axios.all()来同时进行多个请求,等所有请求结束之后返回结果,fetch可以利用Promise.all来实现一样的效果
// 利用axios.all来处理多个请求,所有请求都完成之后resolve
axios.all([
axios.get('https://api.someUrl.com/a'),
axios.get('https://api.someUrl.com/b')
])
.then(axios.spread((a, b) => {
// 利用axios.spread来包裹回调,将返回的结果按顺序放进回调的参数内
console.log(a.data);
console.log(b.data);
}))
.catch(err => {
console.log(err)
});
// fetch里面使用Promise.all来实现相同的效果
Promise.all([
fetch('https://api.someUrl.com/a'),
fetch('https://api.someUrl.com/b')
])
.then(async([res1, res2]) => {
const a = await res1.json();
const b = await res2.json();
console.log(a);
console.log(b);
})
.catch(error => {
console.log(error);
});