第三十五节: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 不同错误,分别弹出对应提示消息。
相关推荐
XIE3921 小时前
TipKit:开源富文本编辑器套件,一套逻辑,任意风格!
前端·笔记·开源
范什么特西1 小时前
一些常用名词
开发语言·前端·javascript
晴天161 小时前
前端打包工具全景解析
前端
晴天161 小时前
Vite vs Webpack 全方位对比
前端·webpack·node.js
体毛旺盛的猿1 小时前
HarmonyOS开发面试题
前端·华为·harmonyos
anOnion2 小时前
构建无障碍组件之Landmarks Pattern
前端·html·交互设计
牧瀬クリスだ2 小时前
前端三件套基础之JS!!!!
前端·javascript
乌夷2 小时前
JavaScript 的事件循环
开发语言·javascript·ecmascript
风骏时光牛马2 小时前
提示词工程:大模型交互的核心塑造技术
前端