axios二次封装-单个、特定的实例的拦截器、所有实例的拦截器。

ts 复制代码
src/service/request/type.ts
import type { AxiosRequestConfig, AxiosResponse } from 'axios'

// 针对AxiosRequestConfig配置进行扩展
export interface HYInterceptors<T = AxiosResponse> {
  requestSuccessFn?: (config: AxiosRequestConfig) => AxiosRequestConfig
  requestFailureFn?: (err: any) => any
  responseSuccessFn?: (res: T) => T
  responseFailureFn?: (err: any) => any
}

export interface HYRequestConfig<T = AxiosResponse> extends AxiosRequestConfig {
  interceptors?: HYInterceptors<T>
}
ts 复制代码
import axios from 'axios'
import type { AxiosInstance } from 'axios'
import type { HYRequestConfig } from './type'

// 拦截器: 蒙版Loading/token/修改配置

/**
 * 两个难点:
 *  1.拦截器进行精细控制
 *    > 全局拦截器
 *    > 实例拦截器
 *    > 单次请求拦截器
 *
 *  2.响应结果的类型处理(泛型)
 */

class HYRequest {
  instance: AxiosInstance

  // request实例 => axios的实例
  constructor(config: HYRequestConfig) {
    this.instance = axios.create(config)

    // 为所有的instance实例都添加拦截器
    this.instance.interceptors.request.use(
      (config) => {
        // 可以添加: loading/token/headers
        return config
      },
      (err) => {
        return err
      }
    )
    this.instance.interceptors.response.use(
      (res) => {
        return res.data
      },
      (err) => {
        return err
      }
    )

    // 针对特定的hyRequest实例添加拦截器
    this.instance.interceptors.request.use(
      config.interceptors?.requestSuccessFn,
      config.interceptors?.requestFailureFn
    )
    this.instance.interceptors.response.use(
      config.interceptors?.responseSuccessFn,
      config.interceptors?.responseFailureFn
    )
  }

  // 封装网络请求的方法
  // T => IHomeData
  request<T = any>(config: HYRequestConfig<T>) {
    // 单次请求的成功拦截处理, 单个请求的拦截器,需要自己手动调用,拦截的本质就是在特定的时候调用,请求拦截器,就是在发送网络请求之前调用。响应拦截器就是在得到后端的结果返回到前台前调用
    if (config.interceptors?.requestSuccessFn) {
      config = config.interceptors.requestSuccessFn(config)
    }

    // 返回Promise
    return new Promise<T>((resolve, reject) => {
      this.instance
        .request<any, T>(config)
        .then((res) => {
          // 单词响应的成功拦截处理
          if (config.interceptors?.responseSuccessFn) {
         	// 重新指定响应结果
            res = config.interceptors.responseSuccessFn(res)
          }
          resolve(res)
        })
        .catch((err) => {
          reject(err)
        })
    })
  }

  get<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'GET' })
  }
  post<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'POST' })
  }
  delete<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'DELETE' })
  }
  patch<T = any>(config: HYRequestConfig<T>) {
    return this.request({ ...config, method: 'PATCH' })
  }
}

export default HYRequest
ts 复制代码
src/service/index.ts
import { BASE_URL, TIME_OUT } from './config'
import HYRequest from './request'

const hyRequest = new HYRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
})
const hyRequest2 = new HYRequest({
  baseURL: BASE_URL,
  timeout: TIME_OUT,
  // 针对hyRequest2实例的特定的请求拦截
  interceptors: {
    requestSuccessFn: (config) => {
      return config
    }
  }
})


export { hyRequest, hyRequest2}
ts 复制代码
src/service/modules/login.ts

import hyRequest from '..'
export function accountLogin(account: any) {
  return hyRequest.post({
    url: '/login',
    data: account,
    // 单个请求的拦截器编写位置
    interceptors:{
    	// 请求成功的拦截器回调
    	responseSuccessFn(config){
    		return config
		}
    }
  })
}

请求拦截器可以编写多个。执行顺序于编写顺序有关,越早编写。请求拦截器就越先执行。响应拦截器的执行顺序与请求拦截器的执行顺序相反

js 复制代码
拦截器知识点介绍
// 一般在使用axios时,会用到拦截器的功能,一般分为两种:请求拦截器、响应拦截器。
// 请求拦截器
//   在请求发送前进行必要操作处理,例如添加统一cookie、请求体加验证、设置请求头等,相当于是对每个接口里相同操作的一个封装;
// 响应拦截器
//   同理,响应拦截器也是如此功能,只是在请求得到响应之后,对响应体的一些处理,通常是数据统一处理等,也常来判断登录失效等。

// 配置全局请求拦截器
// 请求拦截器就是对config进行操作的,然后返回新的config
// axios.interceptors.request.use(请求成功的拦截回调函数,请求失败的拦截回调函数)
axios.interceptors.request.use(
  (config) => {
    //config是请求时的配置信息,里面包含很多关于请求的信息
    // config.url 请求地址、config.headers.xxx = yyy 添加请求头
    // 请求拦截的常用操作
    // 可以对原来的配置进行一些修改:
    // 1. header
    // 2. 认证登录: token/cookie
    // 3. 请求参数进行某些转化

    // 举例:
    // 看一下哪些请求需要验证token,哪些不需要
    // 通过配置文件配置白名单(不需要验证)
    const whiteListApi = ["/a", "/b"]

    // TOEKN存在于localstorage中
    // 获取请求地址:config.url
    if (!whiteListApi.includes(config.url)) {
      // 需要验证token
    } else {
      
    }

    // 也可以设置 发送请求时的等待loading动画
    console.log("请求成功的拦截")
    return config
  },
  (err) => {
    console.log("请求失败的拦截")
    return err
  }
)

// 配置全局响应拦截器
// 响应拦截器就是对res进行操作的, 然后返回新的res
// axios.interceptors.response.use(请求成功的拦截回调函数,请求失败的拦截回调函数)
axios.interceptors.response.use(
  (res) => {
    // res是请求获得的结果
    // 响应拦截的常用操作:
    // 可以对res数据进行处理, 再返回数据
    // 也可以设置请求结束loading动画
    console.log("响应成功的拦截")
    return res.data
  },
  (err) => {
    console.log("响应失败的拦截:", err)
    return err
  }
)

axios
  .get("http://123.207.32.32:9001/lyric?id=500665346")
  .then((res) => {
    console.log("res:", res)
  })
  .catch((err) => {
    console.log("err:", err)
  })
js 复制代码
封装axiosd的必要性
import axios from "axios"
// axios就是axios库默认提供给我们的实例对象
// axios.defaults.xxx  设置的式全局配置,对于所有的axios实例都可见

// 每个实例都是单独, 不会与其他的axios实例的配置(baseURL,TIMEOUT、headers)发生冲突
// 每个实例对象的配置可以设置不同,互不干扰
// const axios实例对象 = axios.create({单独的配置})
const instance1 = axios.create({
  baseURL: "http://123.207.32.32:9001",
  timeout: 6000,
  headers: {}
})

const instance2 = axios.create({
  baseURL: "http://123.207.32.32:8000",
  timeout: 10000,
  headers: {}
})

// 使用实例1发生请求
instance1.get("/lyric", {
  params: {
    id: 500665346
  }
}).then(res => {
  console.log("res:", res.data)
})
相关推荐
老马啸西风8 分钟前
windows wsl2-05-docker 安装笔记
运维·windows·笔记·docker·容器·k8s
老马啸西风14 分钟前
windows docker-02-docker 最常用的命令汇总
linux·运维·ubuntu·docker·容器·eureka·maven
烛阴15 分钟前
Fract - Grid
前端·webgl
JiaLin_Denny29 分钟前
React 实现人员列表多选、全选与取消全选功能
前端·react.js·人员列表选择·人员选择·人员多选全选·通讯录人员选择
sztomarch30 分钟前
Tshark-Tcpdump
linux·运维·网络·测试工具·tcpdump
brzhang33 分钟前
我见过了太多做智能音箱做成智障音箱的例子了,今天我就来说说如何做意图识别
前端·后端·架构
手眼通天王水水39 分钟前
【Linux】3. Shell语言
linux·运维·服务器·开发语言
为什么名字不能重复呢?1 小时前
Day1||Vue指令学习
前端·vue.js·学习
eternalless1 小时前
【原创】中后台前端架构思路 - 组件库(1)
前端·react.js·架构
Moment1 小时前
基于 Tiptap + Yjs + Hocuspocus 的富文本协同项目,期待你的参与 😍😍😍
前端·javascript·react.js