• 9.axios 拦截器的使用,对config 拦截器做的封装


     比如我们在这里发送了请求是没有做任何的一个拦截,之前在前面文章中有写到,如果有多个模块都用到这个请求了,这个请求里面有写共有的逻辑,比如携带token, 显示loading动画。把这些代码可以写到拦截器里面。

    怎么做?

    我们可以 封装 一些对应的类型

    在文件A中封装一些对应的类型接口

    1.先从axios 中倒入对应的类型注解

     2.定义一个对应的类型接口

    3.这个类型接口里面可以定义一些hook,可以让别人通过这个类型接口给我传入哪些hook

    4.要么是我们的 requset 请求拦截器,要么是我们的响应拦截器 response

    5.并且在定义一个接口 来继承 我们的这个AxiosRequestConfig 接口

    6. 并且对原来的类型做一个扩展

    7.封装之后在对应导出

    1. import type { AxiosResponse, AxiosRequestConfig } from 'axios'
    2. //f封装一些对应的类型接口
    3. export interface JYRequestInterceptors {
    4. //1.在这里里面可以定义一些hook,可以让别人通过这个定义的接口给我传入哪些hook
    5. //2.要么是我们的request 拦截器
    6. //拦截
    7. requestinterceptor: (config: AxiosRequestConfig) => AxiosRequestConfig
    8. //错误的拦截
    9. requestinterceptorCatch: (error: any) => any
    10. //响应成功的拦截
    11. responseinterceptor: (res: AxiosResponse) => AxiosResponse
    12. //响应失败错误的拦截
    13. responseinterceptorCatch: (error: any) => any
    14. }
    15. //4.在定义一个JYRequestConfig 接口 继承 AxiosRequestConfig
    16. export interface JYRequestConfig extends AxiosRequestConfig {
    17. //对原来的类型做一个扩展
    18. interceptors: JYRequestInterceptors
    19. }

    在B文件里面做一个引入(在别人创建实例,添加拦截器的一个封装)

    1. import axios from 'axios'
    2. import type { AxiosInstance, AxiosRequestConfig } from 'axios' //instance 和 config 类型注解的倒入
    3. import type { JYRequestInterceptors, JYRequestConfig } from './type'
    4. // axios-->axios instance(实例)
    5. class JYRquest {
    6. instance: AxiosInstance //每次创建出来都用这个实例做一个保存
    7. interceptors?: JYRequestInterceptors
    8. //创建一个类的构造器,这个构造器里面传入类的最基本的配置
    9. constructor(config: JYRequestConfig) {
    10. //axios里面有个create函数,它可以创建出来我们的实例
    11. this.instance = axios.create(config)
    12. this.interceptors = config.interceptors
    13. //3.拦截器
    14. this.instance.interceptors.request.use(
    15. this.interceptors?.requestinterceptor,
    16. this.interceptors?.requestinterceptorCatch
    17. )
    18. //4.响应拦截器
    19. this.instance.interceptors.response.use(
    20. this.interceptors?.responseinterceptor,
    21. this.interceptors?.responseinterceptorCatch
    22. )
    23. }
    24. //封装一个request 函数
    25. request(config: AxiosRequestConfig): void {
    26. this.instance.request(config).then((res) => {
    27. console.log(res)
    28. })
    29. }
    30. }
    31. export default JYRquest

    在出口文件将封装对应的方法进行引入

    1. // service 统一的出口
    2. import JYRquest from './request'
    3. import { BASE_URL, TIME_OUT } from './request/config'
    4. //axios 实例1
    5. const JyRquest = new JYRquest({
    6. baseURL: BASE_URL,
    7. timeout: TIME_OUT,
    8. interceptors: {
    9. requestinterceptor: (config) => {
    10. console.log('请求成功的拦截')
    11. return config
    12. },
    13. requestinterceptorCatch: (err) => {
    14. console.log('请求失败的拦截')
    15. return err
    16. },
    17. responseinterceptor: (res) => {
    18. console.log('响应成功的拦截')
    19. return res
    20. },
    21. responseinterceptorCatch: (err) => {
    22. console.log('响应失败的拦截')
    23. return err
    24. }
    25. }
    26. })
    27. export default JyRquest

    关系逻辑梳理:

    1.首先创建了一个 class JYRequest 的类

    2.这个类在request.ts 文件里面,这个类是允许别人创建多个实例,要不要创建多个实例,根据项目的需求。例如:多个baseURlL 不一样的情况下,就可以去创建多个实例,然后每个实例都可以有自己的baseURL,可以有有自己的config。

    3. 但是大多数项目,都是向一个服务器发送请求,在index.ts 导出的文件里面,是只 new 一     个JYRquest ,这个是一个实例,也叫做一个对象。以后在这个项目里面,只需要用这个对像调用request() 就可以了。或者post、get 这些方法。调的时候,永远都是用的都是这一个实例。

    4.在创建实例的时候的,针对于这个实例对象可以有自己的拦截器,通俗点讲,就是要给当前这个实例对象添加拦截器,把这个拦截器放到config里面,到时候可以从config 里面取到拦截器。

    5.现在添加的拦截器,是所有实例都会有的拦截器

     6.在封装的request 函数中,就不能传让别人传默认的了,因为默认的话它不能传入任何的拦截器,所以这里可以传入 JYRquestConfig ,因为这个是继承AxiosRequestConfig

    1. import axios from 'axios'
    2. import type { AxiosInstance } from 'axios' //instance 和 config 类型注解的倒入
    3. import type { JYRequestInterceptors, JYRequestConfig } from './type'
    4. // axios-->axios instance(实例)
    5. class JYRquest {
    6. instance: AxiosInstance //每次创建出来都用这个实例做一个保存
    7. interceptors?: JYRequestInterceptors
    8. //创建一个类的构造器,这个构造器里面传入类的最基本的配置
    9. constructor(config: JYRequestConfig) {
    10. //axios里面有个create函数,它可以创建出来我们的实例
    11. this.instance = axios.create(config)
    12. this.interceptors = config.interceptors
    13. //3.从config 中取出的拦截器是对应的实例的拦截器
    14. this.instance.interceptors.request.use(
    15. this.interceptors?.requestinterceptor,
    16. this.interceptors?.requestinterceptorCatch
    17. )
    18. //4.响应拦截器
    19. this.instance.interceptors.response.use(
    20. this.interceptors?.responseinterceptor,
    21. this.interceptors?.responseinterceptorCatch
    22. )
    23. //我们可以继续添加所有的实例都有的拦截器
    24. this.instance.interceptors.request.use(
    25. (config) => {
    26. console.log('在我们所有的实例都有的拦截器')
    27. return config
    28. },
    29. (err) => {
    30. return err
    31. }
    32. )
    33. this.instance.interceptors.response.use(
    34. (res) => {
    35. return res
    36. },
    37. (err) => {
    38. return err
    39. }
    40. )
    41. }
    42. //封装一个request 函数
    43. //注意:这里让别人传config 的时候,不能传默认的了, 因为默认的话它不能传入任何的拦截器,所以这里可以传
    44. //这个JYRequestConfig 是继承制 AxiosRequestConfig 的
    45. request(config: JYRequestConfig): void {
    46. //判断里面是否有requestinterceptor 这个函数
    47. if (config.interceptors?.requestinterceptor) {
    48. //如果有这个函数,就将 config =config.interceptors.requestinterceptor(然后将config传进来)
    49. //如果这里真的有这个函数,就执行这个函数
    50. /**
    51. requestinterceptor 这个函数的目的就是对(config),
    52. 做一个转化,转化完之后,还会把默认的config 返回回来,然后再用一个config做一个接收
    53. */
    54. config = config.interceptors?.requestinterceptor(config) //
    55. }
    56. this.instance.request(config).then((res) => {
    57. if (config.interceptors?.responseinterceptor) {
    58. res = config.interceptors.responseinterceptor(res)
    59. }
    60. })
    61. }
    62. }
    63. export default JYRquest

    7.type.ts 文件中 拦截器的设置

    1. import type { AxiosResponse, AxiosRequestConfig } from 'axios'
    2. //f封装一些对应的类型接口
    3. export interface JYRequestInterceptors {
    4. //1.在这里里面可以定义一些hook,可以让别人通过这个定义的接口给我传入哪些hook
    5. //2.要么是我们的request 拦截器
    6. //拦截
    7. requestinterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig
    8. //错误的拦截
    9. requestinterceptorCatch?: (error: any) => any
    10. //响应成功的拦截
    11. responseinterceptor?: (res: AxiosResponse) => AxiosResponse
    12. //响应失败错误的拦截
    13. responseinterceptorCatch?: (error: any) => any
    14. }
    15. //4.在定义一个JYRequestConfig 接口 继承 AxiosRequestConfig
    16. export interface JYRequestConfig extends AxiosRequestConfig {
    17. //对原来的类型做一个扩展
    18. interceptors?: JYRequestInterceptors
    19. }

     8.在main.ts 里面,对请求拦截做一个使用(注意:可以使用拦截,也可以不用)

         

    需求1:对于 每个请求都会携带对应的token

    1.在发送请求的时候携带token,(携带token 应该是我们的请求拦截)

    2.给 header 添加token 就可以了

    3.如果属于实例的拦截的话

    4.如果是属于全局所有的实例都携带的是这一个token ,应当在这里做

    5.假如我们现在是单个实例.

       真实的token 应当都是我们在vuex 中获取的,或者是从服务器中又或者是登录之后从缓存中获取的。但是我们这里举例子,我们这里已经拿到了token,

    1. import JYRquest from './request'
    2. import { BASE_URL, TIME_OUT } from './request/config'
    3. //axios 实例1
    4. const JyRquest = new JYRquest({
    5. baseURL: BASE_URL,
    6. timeout: TIME_OUT,
    7. interceptors: {
    8. requestinterceptor: (config) => {
    9. //真实的token const token=vuex -->login(localStorage)
    10. //如果token 在有值的情况下,把它放到请求头 Authorization 授权的意思
    11. const token=''
    12. if(token){
    13. config.headers.Authorization=`Bearer ${token}` //Bearer 信差的意思,真实开发中,这个都会与token 结合使用
    14. }
    15. console.log('请求成功的拦截')
    16. return config
    17. },
    18. requestinterceptorCatch: (err) => {
    19. console.log('请求失败的拦截')
    20. return err
    21. },
    22. responseinterceptor: (res) => {
    23. console.log('响应成功的拦截')
    24. return res
    25. },
    26. responseinterceptorCatch: (err) => {
    27. console.log('响应失败的拦截')
    28. return err
    29. }
    30. }
    31. })
    32. export default JyRquest

    需求2: 如何在服务器返回数据时候,只返回我们想要的数据

    每次服务器在给我们返回的数据时,除了给了我们返回了我们想要的数据外,还给我们返回了其他的数据 ,这时候我们可以全局的实例拦截中(data的处理)

    需求3: 在拦截器中做状态处理(err的处理)

     

  • 相关阅读:
    《10人以下小团队管理手册》推荐书评
    子查询+UNION+LIMIT
    【Linux】Nignx及负载均衡&动静分离
    java计算机毕业设计高校车辆管理系统MyBatis+系统+LW文档+源码+调试部署
    Python设计模式:你的代码真的够优雅吗?
    leetcode(hot100)——贪心算法
    系统架构的11条原则
    MySQL版数据库原理与应用期末复习重点(1)---关系代数(除运算和自连接查询、手写例题)
    【Vue】Router路由无法跳转问题整理
    西祠胡同社区彻底消失
  • 原文地址:https://blog.csdn.net/weixin_51614564/article/details/125870580