You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3页面刷新时App.vue钩子晚于组件的Axios认证问题求助

解决方案

方案一:全局路由守卫拦截未认证请求

在路由配置中添加全局前置守卫,确保完成认证头设置后再放行进入需要认证的路由,从根源上避免请求提前执行。

  1. 在路由文件(如router/index.js)中添加守卫逻辑:
import store from '@/store'
import mainApi from '@/api/mainApi' // 导入你的Axios实例

router.beforeEach(async (to, from, next) => {
  // 检查是否已配置认证头或store中已标记认证状态
  const hasAuthHeader = mainApi.defaults.headers.common['Authorization']
  const isAuthenticated = store.state.isAuthenticated

  if (!hasAuthHeader && !isAuthenticated) {
    try {
      // 发起认证请求获取token
      const response = await mainApi.post('api/auth/', {
        username: "qweqwe",
        password: "qweqweqwe"
      })
      const token = response.data.token
      // 更新store和全局请求头
      store.commit("setServerToken")
      mainApi.defaults.headers.common['Authorization'] = `Token ${token}`
      mainApi.defaults.headers.common['Accept-Language'] = store.state.language
      if (store.state.isAuthenticated) {
        mainApi.defaults.headers.common['CUSTOM_HEADERS'] = "qweqweqwe"
      }
    } catch (error) {
      console.error('认证失败:', error)
      // 认证失败可跳转到登录页或其他处理逻辑
      return next('/login')
    }
  }
  next()
})
  1. 移除App.vue中mounted/beforeCreate内的getServerTokenAuth逻辑,由路由守卫统一处理认证流程。

方案二:Axios请求拦截器自动补全认证头

给Axios实例添加请求拦截器,每次发起请求前自动检查认证头状态,缺失则先完成认证再继续请求,无需修改路由逻辑。

  1. 在Axios实例配置文件(如api/mainApi.js)中添加拦截器:
import axios from 'axios'
import store from '@/store'

const mainApi = axios.create({
  baseURL: '/api' // 你的接口基础地址
})

// 请求拦截器
mainApi.interceptors.request.use(async (config) => {
  // 检查当前请求是否已携带认证头
  if (!config.headers['Authorization']) {
    // 未携带则先获取token
    const response = await mainApi.post('auth/', {
      username: "qweqwe",
      password: "qweqweqwe"
    })
    const token = response.data.token
    store.commit("setServerToken")
    // 设置全局默认请求头
    mainApi.defaults.headers.common['Authorization'] = `Token ${token}`
    mainApi.defaults.headers.common['Accept-Language'] = store.state.language
    if (store.state.isAuthenticated) {
      mainApi.defaults.headers.common['CUSTOM_HEADERS'] = "qweqweqwe"
    }
    // 为当前请求补全认证头
    config.headers['Authorization'] = `Token ${token}`
  }
  return config
}, (error) => {
  return Promise.reject(error)
})

export default mainApi
  1. 移除App.vue中的认证逻辑,所有Axios请求会自动触发认证流程,确保请求时已携带有效头信息。

方案三:App.vue等待认证完成后再渲染路由组件

在App.vue中先完成认证请求,再渲染router-view,确保路由组件的生命周期钩子在认证完成后执行。

修改App.vue代码:

<template>
  <div id="app">
    <!-- 认证完成后才渲染路由组件 -->
    <router-view v-if="isAuthReady"></router-view>
    <!-- 可选:添加加载提示 -->
    <div v-else>加载中...</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isAuthReady: false
    }
  },
  async created() {
    await this.getServerTokenAuth()
    this.isAuthReady = true
  },
  methods: {
    async getServerTokenAuth(){
      try {
        const response = await this.$mainApi.post('api/auth/', {
          username: "qweqwe",
          password: "qweqweqwe"
        })
        const token = response.data.token
        this.$store.commit("setServerToken")
        this.$mainApi.defaults.headers.common['Authorization'] = `Token ${token}`
        this.$mainApi.defaults.headers.common['Accept-Language'] = this.$store.state.language
        if (this.$store.state.isAuthenticated) {
          this.$mainApi.defaults.headers.common['CUSTOM_HEADERS'] = "qweqweqwe"
        }
      } catch (error) {
        console.error('认证失败:', error)
        this.$router.push('/login')
      }
    }
  }
}
</script>

内容的提问来源于stack exchange,提问作者Wong Yat Cheong Jacky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 11:25:16