跳到主要内容

Axios

Axios 适合放在“请求不只是发出去就完了”的场景里看。它比原生 fetch 重一点,但也把很多项目里常见的事情先收好了:实例、拦截器、超时、统一配置、上传下载进度。

最基础的使用

import axios from 'axios'

const res = await axios.get('/api/users')
console.log(res.data)

为什么项目里常常会选 Axios

  • 实例很好用
  • 请求和响应拦截器顺手
  • JSON 处理默认更省事
  • timeout、baseURL、headers 配置很自然
  • 上传下载进度和取消能力更容易接

一般不会直接裸用

项目里更常见的做法是先建一个实例。

import axios from 'axios'

export const http = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: 10000,
headers: {
'Content-Type': 'application/json',
},
})

请求拦截器

请求拦截器常见用途:

  • 自动带 token
  • 拼统一 header
  • 做 trace id
  • 给某些接口补特殊配置
http.interceptors.request.use((config) => {
const token = localStorage.getItem('token')

if (token) {
config.headers.Authorization = `Bearer ${token}`
}

return config
})

响应拦截器

响应拦截器一般会处理:

  • 统一拿 response.data
  • 业务码判断
  • 登录失效跳转
  • 通用错误提示
http.interceptors.response.use(
(response) => {
return response.data
},
(error) => {
if (error.response?.status === 401) {
// 登录失效逻辑
}

return Promise.reject(error)
}
)

常见请求写法

export function getUserDetail(id: string) {
return http.get(`/users/${id}`)
}

export function createUser(payload: { name: string }) {
return http.post('/users', payload)
}

把接口函数收在 api 层之后,页面里就不需要再关心 URL、method、headers 这些细节。

文件上传

Axios 在这类场景里会更顺手一些。

const formData = new FormData()
formData.append('file', file)

await http.post('/upload', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
onUploadProgress(progressEvent) {
const percent = Math.round(
(progressEvent.loaded / (progressEvent.total || 1)) * 100
)
console.log(percent)
},
})

一个更常见的业务封装方式

通常会分成这几层:

  • http.ts:axios 实例和拦截器
  • api/user.ts:用户接口
  • api/order.ts:订单接口
  • types/:接口类型

这样页面层只关心“调哪个业务函数”,不关心底层请求库细节。

Axios 更适合什么场景

  • 中大型项目
  • 请求层约束比较多
  • 需要统一 token、错误处理、业务码判断
  • 上传下载和文件类接口较多

什么时候还会往上再包一层

Axios 解决的是“请求怎么发更顺”。如果项目开始碰到:

  • 缓存
  • 自动重试
  • 查询失效
  • 预取
  • 乐观更新

那就要继续往 TanStack Query 这一层看。