fetch 和 axios ,两者选谁?
时间:2026-5-20 23:10 作者:独元殇 分类: 前端技术
使用 fetch 主要是因为它是浏览器原生 API ,和经典的 xmlhttpRequest 一样开箱即用,而且 node 也内置。省体积。
而 Axios 是一个体积有十几 kb 的需要 npm i axios 的第三方库。gzip 后只有 5kb 。
不过这个 第三方 库很好用。前端是直接扛业务压力的最后一环。尤其是 HTTP 请求相关,如果自己写不好,那就不用 fetch 原生,而是用第三方库,比如 Axios。
如果你不需要 错误、超时、自动 JSON 或者拦截器等等 实用的功能,或者是想自己手搓,那就不用 Axios 。
今天我简单讲讲两者的异同,让你简单掂量一下有没有必要使用 axios 。
差异
其实 Axios 是把常用的一些功能给封装了。
HTTP 错误(4xx/5xx) , Axios 可以直接 reject 。JSON 里 Axios 能自动 response .data 解析....
然后请求超时了... 取消了... 上传下载的进度查询,Axios 都有现成的库。
cookie 和 CSRF 也有相应的处理措施。
用代码简单的表示一下吧。
1 错误处理:
// Fetch
fetch('/api/user/999')
.then(res => res.ok ? res.json() : Promise.reject(`HTTP ${res.status}`))
.catch(err => console.error('Fetch错误:', err));
// Axios
axios.get('/api/user/999')
.then(res => console.log(res.data))
.catch(err => console.error('Axios错误:', err.response?.status || '网络异常'));
很明显,使用 fetch 的话,有些响应,比如404 和 500 等,你需要写代码手动判断。
而 Axios 内部自动把不是 2xx 的响应,都给你判断好了。
2 发请求
// Fetch
fetch('/api/user',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({name:'Tom'})})
.then(r=>r.json()).then(d=>console.log(d))
// Axios
axios.post('/api/user',{name:'Tom'}).then(res=>console.log(res.data))
是不是 Axios 更优雅,哈哈,直接一个 post 完事。
3 拦截器(我们一般是为了这个,使用 Axios)
// Fetch
const oldFetch=fetch
window.fetch=async(u,o={})=>{ // 重写全局的 fetch
o.headers={...o.headers,Authorization:`Bearer ${getToken()}`}
const r=await oldFetch(u,o)
r.status===401&&(location.href='/login')
return r
}
// Axios
axios.interceptors.request.use(c=>(c.headers.Authorization=`Bearer ${getToken()}`,c))
axios.interceptors.response.use(r=>r.data,e=>(e.response?.status===401&&(location.href='/login'),Promise.reject(e)))
拦截器,是 前端 在发出请求前的处理数据用的。
如果原生 Fetch 的话,直接没有,你得手搓,像我上面写的那样。。。 麻烦死了。
比如我上面写的,拦截所有请求,都带上 token ... 是不是不优雅呀。
这个其实还简单,真实代码里更复杂。
而 Axios 就直接写好了。
第一行,请求统一添加 token ,第二行,响应自动拦截 401 。
不要再造轮子。其他的我都可以手搓,但是 【拦截器】 还是给了我使用 Axios 的理由。
4 处理超时、取消的情况
// 超时
// Fetch
const c=new AbortController(),t=setTimeout(()=>c.abort(),5000)
fetch('/api/data',{signal:c.signal}).finally(()=>clearTimeout(t))
// Axios
axios.get('/api/data',{timeout:5000})
// 取消
// Fetch
const c=new AbortController()
fetch('/api/data',{signal:c.signal})
c.abort()
// Axios
const c=new AbortController()
axios.get('/api/data',{signal:c.signal})
c.abort()
本身 原生 的 fetch 是很笨的,不会自己处理超时的情况。
你得自己手搓超时的业务逻辑代码。
而 Axios 也把这个封装好了。包括取消。但是取消,貌似和原生也差不多。。。
\5. 进度
这个是最后一个优势,如果你要写个 HTTP 进度条的话,那 axios 是不得不选的。如果原生来写的话,得复杂到一坨。axios 一行就 OK 了!
axios.post('/upload',formData,{
onUploadProgress:e=>console.log(Math.round(e.loaded/e.total*100)+'%')
})
这个,就能在 控制台 输出当前的进度了!
基本上能用到的我都写上了,其实 axios 帮的忙也不大,如果没有 进度条 和 拦截器 的需求的话,fetch 完全没太大劣势。毕竟一个请求,能占用多大代码量。