axios请求拦截和响应拦截的理解


01,02内容参考原文:https://blog.csdn.net/qq_59076775/article/details/124877699

结论:
在这里插入图片描述

01. 请求拦截

axios.interceptors.request.use((config)=>{
   return config
},(error)=>{
    return Promise.reject(error)
})

解析:请求拦截这个时候请求还没用发送出去,可以在config里面加一些东西,如在请求头里面携带token,此时还没有到达服务器,error关联的是请求错误返回的信息。举个例子,当你发送请求的时候,这个时候网络被中断,请求还没有到达服务器,但是报错了,这个使用会走error,通常也会进行返回一个Promise对象。

02. 响应拦截

axios.interceptors.response.use((config)=>{
   return config
},(error)=>{
    return Promise.reject(error)
})

解析:此时的请求已经到达了服务器,但是还没有到达客户端,可以对config进行一些操作,例如

进行一层结构的解析,返回return config.data,做一些统一错误处理,请求的时候只管成功,不管失败。error-------------它代表的是响应错误的返回值,如401,404,500的错误,权限不够,参数错误等一些列的错误:

if(status===401){
  alert('权限不够') 
}
else (status===404){
 alert('参数错误')
}
else{
 alert('其它错误')
}

token失效的处理

service.interceptors.response.use(
  (response) => {
      // dosomething
  },
  (error) => {
    // ! 服务器响应失败时,干些事情: 导致响应失败的原因有很多,其中之一是 token 过期
    // 响应失败时的error(错误对象),它经过了axios的2层包装,服务器响应的真实数据在 error.response.data 中。
    // axios包装的提示信息是:error.message,与服务器响应的真实数据是两回事
    const realData = error.response.data
    /* 处理token失效---后端处理 */
    if (error.response && realData && realData.code === 233333) {
      // 以上三个条件全部满足时,才说明token超时
      // 1. 触发actions中的logout函数,清除无效token、当前用户信息
      store.dispatch('user/logout')
      // 2. 跳转到登录页面
      router.push({ path: '/login' })
      // 3. return 一个执行错误,用于终止当前的promise执行链
      return Promise.reject(error)
    } else {
      /*  如果token未失效,则是其他错误 */
      // 1. 提示错误信息
      Message.error(realData.message)
      // 2. return 一个执行错误
      return Promise.reject(error)
    }
  }
)

03. 我的应用

前期框架:

import axios, { InternalAxiosRequestConfig, AxiosResponse } from "axios";

// 创建axios实例
const service = axios.create({
  //  请求的域名,基本地址,proxy 代理时会将“/api”以及前置字符串会被替换为真正域名:   相对路径: /dev-api   或者  绝对路径: http://localhost:8991 ; https://api.example.com
  baseURL: import.meta.env.VITE_APP_BASE_API, // '/dev-api'
  timeout: 50000,
  headers: { "Content-Type": "application/json;charset=utf-8" },
});

//请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    console.log(config, "config--请求拦截器");

    // 操作。。。

    return config;
  },
  (error: any) => {
    console.log(error, "error--请求拦截器");

    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    console.log(response, "response--响应拦截器");

    // 操作。。。。

    // return response.data;
    return response;
  },
  (error: any) => {
    console.log(error, "error--响应拦截器");

    // 操作。。。。

    return Promise.reject(error.message);
  }
);

// 导出axios实例
export default service;

优化:添加一些错误、权限等信息

需要跟后端开发协商好统一的字段,错误代码等信息。

import axios, { InternalAxiosRequestConfig, AxiosResponse } from "axios";
import { TOKEN_KEY } from "@/enums/CacheEnum";
import { ResultEnum } from "@/enums/ResultEnum";
import { ElMessage, ElMessageBox } from "element-plus";
import { useUserStoreHook } from "@/store/modules/user";

// 创建axios实例
const service = axios.create({
  //  请求的域名,基本地址,proxy 代理时会将“/api”以及前置字符串会被替换为真正域名:   相对路径: /dev-api   或者  绝对路径: http://localhost:8991 ; https://api.example.com
  baseURL: import.meta.env.VITE_APP_BASE_API,
  timeout: 50000,
  headers: { "Content-Type": "application/json;charset=utf-8" },
});

//请求拦截器
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    console.log(config, "config--请求拦截器");

    // 操作。。。

    const accessToken = localStorage.getItem(TOKEN_KEY);
    if (accessToken) {
      config.headers.Authorization = accessToken;
    }
    return config;
  },
  (error: any) => {
    console.log(error, "error--请求拦截器");
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response: AxiosResponse) => {
    console.log(response, "response--响应拦截器");

    // 操作。。。

    // 检查配置的响应类型是否为二进制类型('blob' 或 'arraybuffer'), 如果是,直接返回响应对象
    if (
      response.config.responseType === "blob" ||
      response.config.responseType === "arraybuffer"
    ) {
      return response;
    }

    const { code, data, msg } = response.data;
    //成功: SUCCESS = "00000",
    if (code === ResultEnum.SUCCESS) {
      return data;
    }
    ElMessage.error(msg || "系统出错");
    return Promise.reject(new Error(msg || "Error"));
  },
  (error: any) => {
    console.log(error, "error--响应拦截器");

    // 操作。。。。

    // 异常处理
    const { code, msg } = error.response.data;
    // 令牌无效或过期: TOKEN_INVALID = "A0230",
    if (code === ResultEnum.TOKEN_INVALID) {
      ElMessageBox.confirm("", "", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      }).then(() => {
        // 清除token 、重新加载。。。
        const userStore = useUserStoreHook();
        userStore.resetToken().then(() => {
          location.reload();
        });
      });
    } else {
      ElMessage.error(msg || "系统出错");
    }
    return Promise.reject(error.message);
  }
);
// 导出axios实例
export default service;

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
axios是一个基于Promise的HTTP客户端,可以在浏览器和Node.js中使用。二次封装axios可以方便我们在项目中使用统一的请求拦截响应拦截,提高代码复用率和可维护性。 以下是一个axios二次封装的示例代码: ```javascript import axios from 'axios' // 创建axios实例 const instance = axios.create({ baseURL: 'http://api.example.com', // 设置请求的baseURL timeout: 10000 // 设置请求超时时间 }) // 请求拦截器 instance.interceptors.request.use(config => { // 在请求发送之前做些什么 // 可以在请求头中添加token等信息 return config }, error => { // 对请求错误做些什么 return Promise.reject(error) }) // 响应拦截器 instance.interceptors.response.use(response => { // 对响应数据做些什么 return response.data }, error => { // 对响应错误做些什么 return Promise.reject(error) }) export default instance ``` 在上面的代码中,我们通过create方法创建了一个axios实例,然后分别添加了请求拦截器响应拦截器。在请求拦截器中,我们可以对请求进行一些处理,比如在请求头中添加token等信息;在响应拦截器中,我们可以对响应数据进行一些处理,比如统一处理错误信息。 最后,我们将封装好的axios实例导出,就可以在项目中使用了。例如: ```javascript import axios from './axios' axios.get('/user').then(res => { console.log(res) }).catch(err => { console.log(err) }) ``` 这样,我们就可以在项目中使用统一的请求拦截响应拦截了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值