«

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 完全没太大劣势。毕竟一个请求,能占用多大代码量。

标签: 原创 axios fetch