当前位置:   article > 正文

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

axiosrequestconfig

 比如我们在这里发送了请求是没有做任何的一个拦截,之前在前面文章中有写到,如果有多个模块都用到这个请求了,这个请求里面有写共有的逻辑,比如携带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的处理)

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/299717
推荐阅读
相关标签
  

闽ICP备14008679号