Axios封装以及添加拦截器

在前端开发中,http请求层的封装可以极大提升代码的复用性和可维护性,本文将完整的用axios封装接口请求,配置请求与响应拦截器,封装统一的请求方法全过程。

封装的目的和思路

在项目直接用axios发送请求当然没问题,但是如果不做封装,每个请求都需要手动处理token,错误提示等逻辑,容易重复,缺乏统一的loading处理逻辑,不同组件可以用不一致的方式调用axios增加维护成本。业务错误,比如登录失败权限不足不集中处理用户体验差。

所以我们统一封装是为了实现这些目标。

1.封装Axios实例+设置baseURL和超时。

2.添加请求拦截器:自动加token显示Loading

3.添加响应拦截器 统一处理错误隐藏loading

4 暴露统一的get/post等请求方法

5.支持类型推导(泛型)

step1:安装Axios

npm install axios

step2:创建Axios实例并且封装基础配置

javascript 复制代码
// api/request.ts
import axios, { AxiosError } from 'axios'
import { message } from 'antd'
import { showLoading, hideLoading } from './loading'

const instance = axios.create({
  baseURL: '/api',                 // 接口统一前缀
  timeout: 8000,                   // 超时时间
  timeoutErrorMessage: '请求超时,请稍后再试',
  withCredentials: false,          // 是否携带 Cookie
})

为什么要用 axios.create?

可以创建多个实例,分别管理不同的 baseURL(如主站与后台接口)。

不影响全局 axios,互不干扰。

step3:请求拦截器

javascript 复制代码
instance.interceptors.request.use(
  (config) => {
    showLoading()
    const token = localStorage.getItem('token')
    if (token) {
      config.headers.Authorization = 'Token::' + token
    }
    return { ...config }
  },
  (error: AxiosError) => {
    return Promise.reject(error)
  }
)

请求拦截器做了什么?

1.请求前显示 loading(配合 Ant Design 的 Spin)

2.自动从 localStorage 中读取 token,统一加入到请求头中

3.你也可以添加其他自定义 headers,例如用户 ID、语言偏好等

step4:响应拦截器--统一 错误处理以及成功返回data

javascript 复制代码
instance.interceptors.response.use(
  (response) => {
    hideLoading()
    const data = response.data

    if (data.code === 500001) {
      // 登录失效
      message.error(data.msg || '身份已过期,请重新登录')
      localStorage.removeItem('token')
      return Promise.reject(data)
    } else if (data.code !== 0) {
      // 业务错误
      message.error(data.msg || '请求错误,请稍后重试')
      return Promise.reject(data)
    }

    return data.data // 请求成功,返回业务数据
  },
  (error: AxiosError) => {
    hideLoading()
    message.error(error.message || '服务器异常,请稍后重试')
    return Promise.reject(error)
  }
)

拦截器可能有人不理解概念。这里把概念放在这里。

axios.interceptors.request.use 是 Axios 提供的 API,用来设置请求发出前的统一处理逻辑。

它接收两个回调函数,第一个是处理请求体 config 的,我们通常在这里加上 token、显示 loading,处理完之后必须返回 config 否则请求会被中断。

第二个是请求配置阶段发生错误时的处理函数,比如拦截器中抛出异常,这个函数里我们一般把错误通过 Promise.reject 抛出去,供 .catch 捕获使用。

Axios 的响应拦截器也接收两个回调函数,第一个是响应成功时调用,它的参数是 response,从中我们可以提取 response.data,然后判断自定义的 code 字段,来决定是 token 过期、业务出错还是成功。如果 token 过期或失败,会弹出错误提示,并通过 Promise.reject 抛出错误。

第二个回调函数是响应失败(如网络错误、404、500)时触发的,我们可以统一显示"服务器异常"等提示,也用 Promise.reject 抛出错误,供组件用 .catch() 捕获。

后端返回的 data 结构通常如下:

{

"code": 0,

"msg": "成功",

"data": { "userInfo": { ... } }

}

然后我们就可以明显看到我们请求拦截器实际上就是config这个请求体在发送之前我们去加一些逻辑去处理我们的config请求体。比如头部加上Authorization属性值为token把我们的token加上去。还有第二个回调函数,就是把错误作为Promise实例的reject(error)扔出去,这样我们组件可以用.catch捕捉。

响应拦截器同理,response就是我们的响应体。我们响应体在到组件接收之前我们对响应体做一些处理,比如我们不需要响应体,我们只是想要里面的data.data那么成功就返回data.data如果token过期了久调用message这是个组件然后.error显示错误比如token过期了。总之只要有响应体一定会返回data给到我们的组件。如果响应拦截的时候就发现报错了那么就reject扔出error组件.catch捕获。

step5:封装统一请求方法(泛型)

javascript 复制代码
export default {
  get<T>(url: string, params?: object): Promise<T> {
    return instance.get(url, { params })
  },
  post<T>(url: string, params?: object): Promise<T> {
    return instance.post(url, params)
  },
  // 后续可添加 put、delete 等
}

为什么要用泛型 <T>

  • 调用接口时能获得接口返回值的类型提示,增强类型安全

  • 调用时直接写 const res = await api.get<YourType>(...)

step6:如何使用封装后的请求

javascript 复制代码
// api/user.ts
import request from './request'

export const getUserInfo = () => {
  return request.get<{ name: string; age: number }>('/user/info')
}

通过引入对象的形式直接调用里面的方法就可以了,然后声明泛型也就是我们如果需要返回值的话声明返回值的类型。然后后面是传过去的url访问的接口。实际上访问的地址是baseUrl+我们传过去的url。

总结

相关推荐
橘颂TA33 分钟前
【C++】C++11特性的介绍和使用(第三篇)
前端·c++·算法·c++11
GISer_Jing2 小时前
50道JavaScript基础面试题:从基础到进阶
开发语言·javascript·ecmascript
爷_7 小时前
字节跳动震撼开源Coze平台!手把手教你本地搭建AI智能体开发环境
前端·人工智能·后端
charlee449 小时前
行业思考:不是前端不行,是只会前端不行
前端·ai
Amodoro10 小时前
nuxt更改页面渲染的html,去除自定义属性、
前端·html·nuxt3·nuxt2·nuxtjs
Wcowin10 小时前
Mkdocs相关插件推荐(原创+合作)
前端·mkdocs
伍哥的传说10 小时前
CSS+JavaScript 禁用浏览器复制功能的几种方法
前端·javascript·css·vue.js·vue·css3·禁用浏览器复制
Trust yourself24311 小时前
想把一个easyui的表格<th>改成下拉怎么做
前端·深度学习·easyui
三口吃掉你11 小时前
Web服务器(Tomcat、项目部署)
服务器·前端·tomcat