赞
踩
比如我们在这里发送了请求是没有做任何的一个拦截,之前在前面文章中有写到,如果有多个模块都用到这个请求了,这个请求里面有写共有的逻辑,比如携带token, 显示loading动画。把这些代码可以写到拦截器里面。
怎么做?
我们可以 封装 一些对应的类型
在文件A中封装一些对应的类型接口
1.先从axios 中倒入对应的类型注解
2.定义一个对应的类型接口
3.这个类型接口里面可以定义一些hook,可以让别人通过这个类型接口给我传入哪些hook
4.要么是我们的 requset 请求拦截器,要么是我们的响应拦截器 response
5.并且在定义一个接口 来继承 我们的这个AxiosRequestConfig 接口
6. 并且对原来的类型做一个扩展
7.封装之后在对应导出
import type { AxiosResponse, AxiosRequestConfig } from 'axios' //f封装一些对应的类型接口 export interface JYRequestInterceptors { //1.在这里里面可以定义一些hook,可以让别人通过这个定义的接口给我传入哪些hook //2.要么是我们的request 拦截器 //拦截 requestinterceptor: (config: AxiosRequestConfig) => AxiosRequestConfig //错误的拦截 requestinterceptorCatch: (error: any) => any //响应成功的拦截 responseinterceptor: (res: AxiosResponse) => AxiosResponse //响应失败错误的拦截 responseinterceptorCatch: (error: any) => any } //4.在定义一个JYRequestConfig 接口 继承 AxiosRequestConfig export interface JYRequestConfig extends AxiosRequestConfig { //对原来的类型做一个扩展 interceptors: JYRequestInterceptors }
在B文件里面做一个引入(在别人创建实例,添加拦截器的一个封装)
- import axios from 'axios'
- import type { AxiosInstance, AxiosRequestConfig } from 'axios' //instance 和 config 类型注解的倒入
- import type { JYRequestInterceptors, JYRequestConfig } from './type'
- // axios-->axios instance(实例)
- class JYRquest {
- instance: AxiosInstance //每次创建出来都用这个实例做一个保存
- interceptors?: JYRequestInterceptors
- //创建一个类的构造器,这个构造器里面传入类的最基本的配置
- constructor(config: JYRequestConfig) {
- //axios里面有个create函数,它可以创建出来我们的实例
- this.instance = axios.create(config)
- this.interceptors = config.interceptors
- //3.拦截器
- this.instance.interceptors.request.use(
- this.interceptors?.requestinterceptor,
- this.interceptors?.requestinterceptorCatch
- )
- //4.响应拦截器
- this.instance.interceptors.response.use(
- this.interceptors?.responseinterceptor,
- this.interceptors?.responseinterceptorCatch
- )
- }
- //封装一个request 函数
- request(config: AxiosRequestConfig): void {
- this.instance.request(config).then((res) => {
- console.log(res)
- })
- }
- }
- export default JYRquest
-
在出口文件将封装对应的方法进行引入
- // service 统一的出口
- import JYRquest from './request'
- import { BASE_URL, TIME_OUT } from './request/config'
- //axios 实例1
- const JyRquest = new JYRquest({
- baseURL: BASE_URL,
- timeout: TIME_OUT,
- interceptors: {
- requestinterceptor: (config) => {
- console.log('请求成功的拦截')
- return config
- },
- requestinterceptorCatch: (err) => {
- console.log('请求失败的拦截')
- return err
- },
- responseinterceptor: (res) => {
- console.log('响应成功的拦截')
- return res
- },
- responseinterceptorCatch: (err) => {
- console.log('响应失败的拦截')
- return err
- }
- }
- })
- 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 的
import axios from 'axios' import type { AxiosInstance } from 'axios' //instance 和 config 类型注解的倒入 import type { JYRequestInterceptors, JYRequestConfig } from './type' // axios-->axios instance(实例) class JYRquest { instance: AxiosInstance //每次创建出来都用这个实例做一个保存 interceptors?: JYRequestInterceptors //创建一个类的构造器,这个构造器里面传入类的最基本的配置 constructor(config: JYRequestConfig) { //axios里面有个create函数,它可以创建出来我们的实例 this.instance = axios.create(config) this.interceptors = config.interceptors //3.从config 中取出的拦截器是对应的实例的拦截器 this.instance.interceptors.request.use( this.interceptors?.requestinterceptor, this.interceptors?.requestinterceptorCatch ) //4.响应拦截器 this.instance.interceptors.response.use( this.interceptors?.responseinterceptor, this.interceptors?.responseinterceptorCatch ) //我们可以继续添加所有的实例都有的拦截器 this.instance.interceptors.request.use( (config) => { console.log('在我们所有的实例都有的拦截器') return config }, (err) => { return err } ) this.instance.interceptors.response.use( (res) => { return res }, (err) => { return err } ) } //封装一个request 函数 //注意:这里让别人传config 的时候,不能传默认的了, 因为默认的话它不能传入任何的拦截器,所以这里可以传 //这个JYRequestConfig 是继承制 AxiosRequestConfig 的 request(config: JYRequestConfig): void { //判断里面是否有requestinterceptor 这个函数 if (config.interceptors?.requestinterceptor) { //如果有这个函数,就将 config =config.interceptors.requestinterceptor(然后将config传进来) //如果这里真的有这个函数,就执行这个函数 /** requestinterceptor 这个函数的目的就是对(config), 做一个转化,转化完之后,还会把默认的config 返回回来,然后再用一个config做一个接收 */ config = config.interceptors?.requestinterceptor(config) // } this.instance.request(config).then((res) => { if (config.interceptors?.responseinterceptor) { res = config.interceptors.responseinterceptor(res) } }) } } export default JYRquest7.type.ts 文件中 拦截器的设置
import type { AxiosResponse, AxiosRequestConfig } from 'axios' //f封装一些对应的类型接口 export interface JYRequestInterceptors { //1.在这里里面可以定义一些hook,可以让别人通过这个定义的接口给我传入哪些hook //2.要么是我们的request 拦截器 //拦截 requestinterceptor?: (config: AxiosRequestConfig) => AxiosRequestConfig //错误的拦截 requestinterceptorCatch?: (error: any) => any //响应成功的拦截 responseinterceptor?: (res: AxiosResponse) => AxiosResponse //响应失败错误的拦截 responseinterceptorCatch?: (error: any) => any } //4.在定义一个JYRequestConfig 接口 继承 AxiosRequestConfig export interface JYRequestConfig extends AxiosRequestConfig { //对原来的类型做一个扩展 interceptors?: JYRequestInterceptors }8.在main.ts 里面,对请求拦截做一个使用(注意:可以使用拦截,也可以不用)
1.在发送请求的时候携带token,(携带token 应该是我们的请求拦截)
2.给 header 添加token 就可以了
3.如果属于实例的拦截的话
4.如果是属于全局所有的实例都携带的是这一个token ,应当在这里做
5.假如我们现在是单个实例.
真实的token 应当都是我们在vuex 中获取的,或者是从服务器中又或者是登录之后从缓存中获取的。但是我们这里举例子,我们这里已经拿到了token,
import JYRquest from './request' import { BASE_URL, TIME_OUT } from './request/config' //axios 实例1 const JyRquest = new JYRquest({ baseURL: BASE_URL, timeout: TIME_OUT, interceptors: { requestinterceptor: (config) => { //真实的token const token=vuex -->login(localStorage) //如果token 在有值的情况下,把它放到请求头 Authorization 授权的意思 const token='' if(token){ config.headers.Authorization=`Bearer ${token}` //Bearer 信差的意思,真实开发中,这个都会与token 结合使用 } console.log('请求成功的拦截') return config }, requestinterceptorCatch: (err) => { console.log('请求失败的拦截') return err }, responseinterceptor: (res) => { console.log('响应成功的拦截') return res }, responseinterceptorCatch: (err) => { console.log('响应失败的拦截') return err } } }) export default JyRquest
每次服务器在给我们返回的数据时,除了给了我们返回了我们想要的数据外,还给我们返回了其他的数据 ,这时候我们可以全局的实例拦截中(data的处理)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。