Fetch是浏览器原生API,轻量但功能基础,需手动处理请求序列化、错误检查和响应解析(如
.json()),仅网络错误会触发reject。
Axios作为第三方库功能全面,支持自动数据序列化、HTTP错误自动reject、拦截器、进度监控及更简洁的API(如直接设置
timeout)。
关键差异:
- 错误处理 :Axios自动捕获HTTP错误,Fetch需手动检查
response.ok- 易用性 :Axios开箱即用,Fetch需额外封装(如请求取消需
AbortController)- 兼容性:Axios支持旧浏览器,Fetch需polyfill
选择建议:
- 简单项目或减少依赖时用Fetch;
- 中大型项目或需要高级功能(拦截器、统一错误处理)时推荐Axios;
两者均支持现代取消请求(
AbortController),但Axios提供更完善的开发体验。
fetch 和 axios 的核心对比总结
| 特性 | fetch (浏览器原生) | axios (第三方库) |
|---|---|---|
| 来源/依赖 | 现代浏览器原生 API,无需安装 | 第三方库,需安装 (npm install axios) |
| 请求与响应格式 | 请求体需手动序列化(如 JSON.stringify()),响应需调用 .json() 等方法解析 |
自动序列化请求数据,响应默认自动解析 JSON |
| 错误处理 | 仅对网络错误 reject,HTTP 错误状态(如 404、500)不会 reject,需手动检查 response.ok |
HTTP 错误状态会自动 reject,可在 catch 中统一处理 |
| 请求取消 | 使用 AbortController(较新的 API) |
支持 CancelToken(旧版)和 AbortController(新版) |
| 拦截器 | 无原生拦截器,需手动封装 | 提供请求/响应拦截器,便于全局处理 |
| 超时设置 | 不支持原生超时设置,需结合 AbortController 实现 |
支持通过 timeout 配置直接设置 |
| 浏览器兼容性 | 现代浏览器支持,IE 不支持(需 polyfill) | 兼容性好,支持旧版浏览器(包括 IE) |
| 请求进度监控 | 不支持 | 支持上传/下载进度监控 |
| CSRF/XSRF 防护 | 需手动设置 | 支持内置配置 |
| 并发请求 | 可使用 Promise.all() |
提供 axios.all() 和 axios.spread()(现已较少用) |
补充说明:
-
fetch 更轻量(原生),但功能相对基础,需额外封装。
-
axios 功能全面,开箱即用,适合复杂应用。
-
选择建议:
-
简单项目或需减少依赖时,可选
fetch。 -
中大型项目或需要拦截器、自动错误处理等功能时,推荐
axios。
-
可根据具体项目需求选择合适的方式。
Fetch 与 Axios 常用 API 对比表格
| 功能类别 | fetch | axios |
|---|---|---|
| 基本 GET 请求 | fetch('/api/data') |
axios.get('/api/data') |
| 基本 POST 请求 | fetch('/api/data', { method: 'POST', body: JSON.stringify(data) }) |
axios.post('/api/data', data) |
| 配置请求方法 | fetch(url, { method: 'PUT', body: data }) |
axios.put(url, data) axios.delete(url) axios.patch(url, data) |
| 请求头设置 | fetch(url, { headers: { 'Content-Type': 'application/json' } }) |
axios.get(url, { headers: { 'Content-Type': 'application/json' } }) |
| URL 参数/查询参数 | 手动拼接:fetch(/api/data?id=${id}) 或使用 URLSearchParams |
axios.get('/api/data', { params: { id: 123 } }) |
| 请求体数据 | 需手动序列化: body: JSON.stringify(data) |
自动序列化: data: data (自动转为JSON) |
| 响应数据获取 | response.json() (JSON) response.text() (文本) response.blob() (二进制) |
response.data (自动根据响应类型解析) |
| 超时设置 | 需结合 AbortController 实现: <br>const controller = new AbortController();<br>setTimeout(() => controller.abort(), 5000);<br>fetch(url, { signal: controller.signal })<br> |
直接配置: axios.get(url, { timeout: 5000 }) |
| 请求取消 | 使用 AbortController: <br>const controller = new AbortController();<br>fetch(url, { signal: controller.signal });<br>controller.abort(); // 取消请求<br> |
旧版:CancelToken 新版:AbortController |
| 全局配置 | 无原生支持,需自行封装 | axios.defaults.baseURL = '...' axios.defaults.headers.common['Authorization'] = '...' |
| 创建实例 | 无 | const instance = axios.create({ baseURL: '...' }) |
| 拦截器 | 无原生支持,需自行封装 | 请求拦截器: axios.interceptors.request.use() 响应拦截器: axios.interceptors.response.use() |
| 错误处理 | 需检查 response.ok: <br>if (!response.ok) {<br> throw new Error('HTTP错误');<br>}<br> |
HTTP 错误码自动进入 catch 可配置 validateStatus |
| 并发请求 | Promise.all([fetch(url1), fetch(url2)]) |
axios.all([req1, req2]) 或 Promise.all |
| 响应状态信息 | response.status (状态码) response.statusText (状态文本) response.headers (响应头) |
response.status response.statusText response.headers response.config (请求配置) |
| 请求进度监控 | 有限支持: response.body 通过 ReadableStream |
支持上传/下载进度: <br>{<br> onUploadProgress: (progressEvent) => {},<br> onDownloadProgress: (progressEvent) => {}<br>}<br> |
| withCredentials | { credentials: 'include' } |
{ withCredentials: true } |
使用示例对比
GET 请求示例
javascript
// fetch
fetch('/api/users?page=2')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// axios
axios.get('/api/users', { params: { page: 2 } })
.then(response => console.log(response.data))
.catch(error => console.error('Error:', error));
POST 请求示例
javascript
// fetch
fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'John', age: 30 })
})
.then(response => response.json())
.then(data => console.log(data));
// axios
axios.post('/api/users', { name: 'John', age: 30 })
.then(response => console.log(response.data));
错误处理示例
javascript
// fetch
fetch('/api/users/999')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// axios
axios.get('/api/users/999')
.then(response => console.log(response.data))
.catch(error => {
if (error.response) {
console.error('HTTP Error:', error.response.status);
} else {
console.error('Error:', error.message);
}
});
选择建议
-
使用 fetch:项目简单、不想增加依赖、现代浏览器环境
-
使用 axios:需要完整功能、良好错误处理、拦截器、向后兼容
两种方式在实际项目中都很常见,选择取决于具体需求和团队偏好。