第三十五节:Axios 统一错误拦截、401 Token 过期处理

第三十五节:Axios 统一错误拦截、401 Token 过期处理

目标:统一处理后端返回错误码,全局消息提示;401 时清除 pinia 用户状态、跳转到登录页,实现 token 过期自动登出。

1、改造 src/utils/request.js(axios 二次封装)

复制代码
import axios from 'axios'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/stores/user'

// 创建axios实例
const service = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL,
  timeout: 10000
})

// 请求拦截器:带上token
service.interceptors.request.use(config => {
  const userStore = useUserStore()
  if(userStore.token){
    config.headers.Authorization = `Bearer ${userStore.token}`
  }
  return config
}, error => {
  return Promise.reject(error)
})

// 响应拦截器:统一处理返回码
service.interceptors.response.use(
  response => {
    const res = response.data
    //业务码200代表正常
    if(res.code !== 200){
      ElMessage.error(res.msg || '请求失败')
      return Promise.reject(new Error(res.msg || 'Error'))
    }
    return res
  },
  error => {
    // http状态码错误处理
    const userStore = useUserStore()
    if(error.response){
      const status = error.response.status
      switch(status){
        case 401:
          ElMessage.warning('登录已过期,请重新登录')
          //清空token、用户信息
          userStore.logout()
          //跳转到登录页
          location.href = '/login'
          break
        case 403:
          ElMessage.error('没有权限访问该资源')
          break
        case 404:
          ElMessage.error('请求接口不存在')
          break
        case 500:
          ElMessage.error('服务器内部错误')
          break
        default:
          ElMessage.error(error.message || '网络异常')
      }
    }else{
      ElMessage.error('网络连接失败,请检查网络')
    }
    return Promise.reject(error)
  }
)

export default service

2、完善 user 仓库 logout 方法 src/stores/user.js

补充 logout,清除 token、用户信息

复制代码
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user',{
  state:()=>{
    return {
      token:'',
      username:'',
      roles:[]
    }
  },
  actions:{
    setToken(token){
      this.token = token
    },
    setUserInfo(info){
      this.username = info.username
      this.roles = info.roles
    },
    //退出登录、清空状态
    logout(){
      this.token = ''
      this.username = ''
      this.roles = []
    }
  },
  persist:true
})

3、mock 模拟 401 测试(可选)

在 mock 接口中,返回 http 状态 401,即可触发过期逻辑:

复制代码
'/api/getUserInfo': ({headers})=>{
  //简单模拟token失效
  if(!headers.authorization){
    return { code:401, msg:'token失效' }
  }
  return {
    code:200,
    data:{ username:'admin', roles:['admin'] }
  }
}

测试流程

  1. 正常请求接口,后端返回 code 非 200,页面自动弹出错误提示。
  2. 触发 401 状态码:弹出提示,清空 pinia 存储,页面自动跳转到登录页面。
  3. 403/404/500 不同错误,分别弹出对应提示消息。
相关推荐
FRing0323 分钟前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2
Penge6662 小时前
《Go 后端开发者学 TypeScript:typescript 类型断言》
javascript
Penge6662 小时前
《Go 后端开发者学 TypeScript:Symbol》
javascript
疯华整猫3 小时前
被杀掉之后:我把 Android 的「唤起 + 常驻」重做了一遍
前端·面试·架构
ruanno_top4 小时前
点全选,已选的被清空了:Transfer 三态复选框的三个 bug
vue.js
三*一4 小时前
Mapbox‑GL JS 多边形折点编辑工具:实现原理、功能拆解与踩坑总结
开发语言·javascript·ecmascript
时间的情敌5 小时前
Cesium 加载 3D Tiles 倾斜摄影、压平、样式设置(Vue3 实战)
vue.js·3d·cesium
IT_陈寒5 小时前
Java开发实战:从入门到精通
前端·人工智能·后端
FungLeo6 小时前
成为全栈·基础补充·Node.js 运行时:事件循环与异步
javascript·node.js·事件循环·后端开发·异步编程·成为全栈
风骏时光牛马6 小时前
生成一个AI转岗经历标题,只需要一个标题,不需要其他的任何文本。
前端