Vue 3登录后Axios全局x-access-token请求头不生效 刷新才正常
问题核心原因
你遇到的跳转后请求不带鉴权头、刷新才生效的问题,根源是Axios全局请求头的赋值执行时机完全不对:
- 你写在
main.js里的axios.defaults.headers['x-access-token'] = localStorage.getItem('accessToken'),只会在Vue应用首次完成初始化、全量加载页面的那个节点执行一次 - 应用刚启动时,用户还没进入登录流程,
localStorage里根本没有存过有效token,这行代码实际取到的值是null,直接把Axios的全局鉴权头设成了空值 - 后续登录成功往
localStorage写token的操作,完全不会触发Axios全局配置的更新——因为全局配置早在启动时就已经按空值初始化完了,所以SPA无刷新路由跳转后发起的请求,携带的还是之前初始化的空请求头 - 手动按F5刷新时,整个Vue应用重新走初始化流程,
main.js代码重新执行,这时候localStorage里已经有之前存的token了,所以请求头配置才会正确生效
修复实现
方案1:用Axios请求拦截器动态注入鉴权头(生产环境推荐写法)
不要用固定值写死全局请求头,替换main.js里的原有配置,改成在每个请求实际发出的瞬间,动态从本地存储读最新的token值:
// main.js 中替换原有的固定请求头赋值代码 axios.interceptors.request.use( (config) => { const accessToken = localStorage.getItem('accessToken') // 本地存了有效token时,自动给当前请求加上鉴权头 if (accessToken) { config.headers['x-access-token'] = accessToken } return config }, (err) => Promise.reject(err) )
这种写法不需要在登录、token刷新等节点手动操作Axios配置,不管token是什么时候存入本地的,每次发请求都会自动取最新值带上,从根源上避免时机不匹配的问题。
方案2:登录成功后手动同步全局配置(临时快速修复)
如果不想调整拦截器逻辑,至少要在登录成功存完token之后,手动同步更新一次Axios的全局默认请求头,修改你的登录回调逻辑:
axios.post('auth/signin', { username: username, password: password }).then((response) => { const { accessToken, refreshToken } = response.data localStorage.setItem('accessToken', accessToken) localStorage.setItem('refreshToken', refreshToken) // 新增:存入token后立刻同步更新Axios全局请求头 axios.defaults.headers['x-access-token'] = accessToken toast.success("Login sukses") // 优化:只解码一次token,复用变量,避免重复读localStorage const tokenPayload = VueJwtDecode.decode(accessToken) if(tokenPayload.sub == "admin"){ router.push({name: 'admin.dashboard.index'}) }else if(tokenPayload.sub == "user"){ router.push({name: 'user.dashboard.index'}) }else if(tokenPayload.sub == "company"){ router.push({name: 'company.dashboard.index'}) } }).catch(error => { toast.error(error.response.data.error.message); })
注:这种写法只适合临时快速上线修复,长期维护成本高——后续如果遇到token自动刷新、用户退出登录、多端同步登出等场景,都需要手动同步修改一次Axios全局配置,漏改就会再次出现请求头缺失的问题。
内容的提问来源于stack exchange,提问作者ASHafizullah
相关产品推荐
相关产品推荐

