axios封装请求、axios拦截器

147 阅读2分钟

本文中的实例,是神舟记账项目的。

axios 封装请求

封装要做的事:

  1. 鉴于axios封装并不好用,考虑使用中间层,即用HttpClient的类对axios进行封装,好处是可以修改参数,因为axios的参数都是固定的,同时也方便维护;
  2. 做统一的错误处理。(发送频繁429或其他的状态码)
  3. 加载中
  • 新建http.tsx封装axios和拦截:
// src/shared/Http.tsx
// 先声明类,定义增删改查操作CRUD,再声明函数
import axios, {AxiosInstance} from "axios";
export class Http{
    instance:AxiosInstance         // 引入 Axios 实例
    constructor(baseURL:string){   // 构造函数,传基础参数
      this.instance = axios.create({baseURL})
    }   
    get(){}           // read           
    post(){}          // create
    patch(){}         // update
    delete(){}        // destroy
}
export const http = new Http()

填充具体内容:

import axios, {AxiosInstance} from "axios";
export class Http{
    instance:AxiosInstance         // 引入 Axios 实例
    constructor(baseURL:string){   // 构造函数,传基础参数
      this.instance = axios.create({baseURL})  // 初始化
    }
    // get 接受一个泛型,用来表示返回值的类型,其余的方法区别在于 method
    // get 的第 2 个形参为 query 类型是对象 Record ,其中key为string,value为JSONValue
    get<R = unknown>(url: string, query?: Record<string, JSONValue>, config?: GetConfig){
      return this.instance.request<R>({...config, url: url, params: query, method: "get"});
    }           
    post(){}          // create
    patch(){}         // update
    delete(){}        // destroy
}

封装统一的拦截

export const http = new Http('/api/v1')

http.instance.interceptors.request.use(config => {}, ()=>{})
http.instance.interceptors.response.use(config => {}, ()=>{})

在业务界面使用封装的Http

// SignInPage.tsx
const onClickSendValidationCode = async () => {
  const response = await http.post('/api/v1/validation_codes', { email: formData.email })
  .catch(()=>{})
  refValidationCode.value.startCount()
}

axios拦截器的使用

用户在点击发送验证码后,短时间内再次点击按钮,就要拦截这次频繁操作的请求,否则就会错乱

axios作弊表,里面有详细的用法

http.instance.interceptors.response.use(response => {
  console.log('response')
}, (error)=>{
  console.log('error')  // error 的类型有很多
  if(error.response){
    const axiosError = error as AxiosError
    if(axiosError.response?.status === 429){
        alert('请求太频繁了')
    }
  }
  throw error
})

具体的业务错误,放在业务中条件判断;共有的错误放在http或拦截器里面条件判断,比如频繁点击