axios更适配复杂场景:默认抛出非2xx错误、自动序列化JSON、支持上传进度、拦截器和请求取消;fetch需手动处理cookie、状态码、序列化等,默认行为过于底层。
直接说结论:如果你只是想快速发个 GET 请求,fetch 足够;但只要涉及错误处理、请求取消、上传进度、自动序列化 JSON 或统一拦截逻辑,axios 省事得多。
fetch 默认不会携带 Cookie,也不会把 4xx/5xx 状态码当错误抛出——它只在真正“网络失败”(如断网、DNS 失败)时才 reject。这意味着你得手动检查 response.ok,否则 401 登录过期会静默返回空数据。
{ credentials: 'include' }
if (!res.ok) throw new Error(...) 才能进 catch
axios 默认不带 cookie,但设 withCredentials: true 后行为更可控;且默认对非 2xx 状态码 rejectfetch('/api/user', { credentials: 'include' })
.then(res => {
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
})
.catch(err => console.error('请求失败:', err));
用 fetch 发 POST JSON,你得自己 JSON.stringify、手动设 Content-Type: application/json;而 axios 对 data: { a: 1 } 会自动处理这两步,还支持 transformRequest 拓展。
fetch 的 body 只接受 string、FormData、Blob 等,不能直接传对象axios 的 data 字段接受任意类型,根据配置自动适配(比如传 FormData 就不设 Content-Type)axios 可监听 onUploadProgress,fetch 没原生支持axios.post('/api/upload', formData, {
onUploadProgress: e => console.log(`${e.loaded}/${e.total}`)
});
fetch 支持 AbortController 取消,但只能取消单个请求;axios 提供 CancelToken(旧版)或 AbortController(v0.22+),更重要的是它的请求/响应拦截器能统一加 token、处理错误弹窗、记录日志等。
AbortController 实例并 abort 旧的axios.interc
eptors.request.use 可自动注入 Authorization headerreturn Promise.reject(...) 可提前中断请求链,fetch 没对应机制真正用起来,多数项目最终都会封装一层 fetch 或直接切到 axios——因为默认行为太“裸”,补全后代码量并不比 axios 少。