016-fetch & axios

Fetch 与 Axios 详解(JavaScript HTTP 请求工具)


1. Fetch API(现代浏览器原生支持)

核心特点

  • 浏览器原生 API(无需安装)
  • 基于 Promise 设计
  • 符合现代 Web 标准

基本用法

1
2
3
4
5
6
7
fetch(url, options)
.then(response => {
if (!response.ok) throw new Error('HTTP error');
return response.json(); // 解析为JSON
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

关键配置项(options)

1
2
3
4
5
6
7
8
9
10
11
{
method: 'POST', // GET, PUT, DELETE 等
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
},
body: JSON.stringify(data), // POST/PUT 数据
mode: 'cors', // cors, no-cors, same-origin
cache: 'no-cache', // 缓存控制
credentials: 'include' // 携带cookie
}

优势

  • 零依赖、轻量级
  • 流式数据处理支持(response.body
  • 符合 Web 标准,未来兼容性好

缺点

  • 不自动处理错误状态码(404/500 不会触发 catch)
  • 需手动转换响应数据(需调用 .json()/.text()
  • 不支持请求超时设置(需用 AbortController 实现)
  • 默认不携带 cookie
  • 无请求/响应拦截器

超时处理示例

1
2
3
4
5
6
7
8
9
10
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000); // 5秒超时

fetch(url, {
signal: controller.signal
}).catch(err => {
if (err.name === 'AbortError') {
console.log('请求超时');
}
});

2. Axios(第三方库)

核心特点

  • 功能丰富的 HTTP 客户端
  • 支持浏览器和 Node.js
  • 自动转换 JSON 数据

安装

1
2
3
npm install axios
# 或
yarn add axios

基本用法

1
2
3
4
5
6
7
axios.get(url, { params: { id: 1 } })
.then(response => console.log(response.data))
.catch(error => console.error(error));

axios.post(url, { name: 'John' }, {
headers: { 'X-Custom-Header': 'value' }
});

关键特性

功能 示例/说明
自动JSON转换 响应数据自动解析到 response.data
错误处理 400/500 状态码自动触发 catch
并发请求 axios.all([req1, req2])
拦截器 见下方示例
取消请求 使用 CancelTokenAbortController
进度监控 onUploadProgress 事件
CSRF防护 自动处理 XSRF-TOKEN

拦截器示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 请求拦截器
axios.interceptors.request.use(config => {
config.headers.Auth = 'Bearer token'; // 自动添加token
return config;
});

// 响应拦截器
axios.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
// 统一处理未授权错误
}
return Promise.reject(error);
}
);

取消请求示例

1
2
3
4
5
6
7
8
9
10
11
const source = axios.CancelToken.source();

axios.get(url, { cancelToken: source.token })
.catch(thrown => {
if (axios.isCancel(thrown)) {
console.log('请求取消:', thrown.message);
}
});

// 取消请求
source.cancel('用户取消操作');

3. Fetch vs Axios 核心对比

特性 Fetch Axios
安装 浏览器原生 需安装第三方库
响应处理 需手动调用 .json() 自动解析 JSON 数据
错误处理 不 reject HTTP 错误 自动 reject 非 2xx 响应
超时设置 需用 AbortController 内置 timeout 参数
拦截器 不支持 支持请求/响应拦截器
进度跟踪 通过 ReadableStream 实现 内置 onUploadProgress
取消请求 AbortController CancelToken / AbortController
浏览器支持 现代浏览器(IE 需 polyfill) 广泛支持(含 IE11)
CSRF/XSRF 需手动处理 自动防御
并发 Promise.all axios.all + axios.spread
请求体数据类型 需手动序列化 自动处理对象数据

4. 使用场景推荐

  • 推荐使用 Fetch 的场景

    • 小型项目或简单请求
    • 需要最小化依赖
    • 使用现代浏览器且不需要高级功能
    • 需要流式数据处理(如大文件下载)
  • 推荐使用 Axios 的场景

    • 企业级应用
    • 需要统一错误处理
    • 需要请求拦截(如自动添加 token)
    • 需要上传进度条等高级功能
    • 兼容旧版浏览器(如 IE11)

5. 最佳实践示例

Fetch 高级封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
async function safeFetch(url, options = {}) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000);

try {
const response = await fetch(url, {
...options,
credentials: 'include',
signal: controller.signal
});

clearTimeout(timeoutId);

if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
throw new Error(`请求失败: ${error.message}`);
}
}

Axios 实例封装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 10000,
headers: { 'Content-Type': 'application/json' }
});

// 添加请求拦截器
api.interceptors.request.use(config => {
config.headers.Authorization = `Bearer ${getToken()}`;
return config;
});

// 使用封装实例
api.get('/users')
.then(({ data }) => console.log(data));

6. 总结

  • Fetch:轻量级原生解决方案,适合简单场景和现代浏览器,但需自行封装高级功能
  • Axios:功能全面的 HTTP 客户端,提供开箱即用的高级特性(拦截器、取消请求等),适合复杂项目
  • 选择建议
    • 优先考虑项目复杂度而非技术新颖性
    • 新项目可首选 Axios 减少重复封装
    • 对包体积敏感的场景(如微前端)可选用 Fetch
    • 考虑团队熟悉度和维护成本