NuxtJS刷新Token后重发请求 Vue组件未更新问题解决方案
NuxtJS刷新Token重发请求后组件无响应更新问题
问题场景
NuxtJS前端对接Laravel API后端时,全局Axios拦截器捕获401鉴权失败请求后,调用刷新Token接口获取新凭证,再重发原失败请求。实际运行中重发的请求可正常返回200成功结果,但发起原请求的Vue组件没有同步更新,拿不到重发后的返回数据。
原有实现代码
401错误拦截器
$axios.onError(error => { if (error.response.status === 401) { app.$auth.useRefreshToken().then(() => { error.config.headers['Authorization'] = `Bearer ${app.$auth.accessToken}` $axios.request(error.config) }) } })
并发刷新请求合并逻辑(该部分运行正常)
useRefreshToken() { if (this.refreshTokenPromise instanceof Promise) { return this.refreshTokenPromise } const refreshTokenPromise = this.PKCERetrieveTokens({ grantType: 'refresh_token', refreshToken: this.$store.state.auth.refreshToken }).then(() => this.setRefreshTokenPromise(null)) this.setRefreshTokenPromise(refreshTokenPromise) return refreshTokenPromise }
问题原因
拦截器里没有把刷新Token、重发请求的Promise链返回给原调用方。组件发起第一次请求时拿到的是401的失败结果,拦截器内部发起的重发请求是独立的异步调用,和原组件的请求调用链完全断开,重发拿到的数据自然没法传回组件触发响应式更新。
修复方案
修改拦截器逻辑,把整个重试流程的Promise结果沿原调用链返回,同时增加重试标记避免死循环:
$axios.onError(error => { // 仅处理401错误,且标记未重试过的请求,防止无限重试 if (error.response?.status === 401 && !error.config._isRetried) { error.config._isRetried = true // 返回刷新Token的Promise链 return app.$auth.useRefreshToken().then(() => { // 替换新的有效Token error.config.headers['Authorization'] = `Bearer ${app.$auth.accessToken}` // 必须return重发的请求,让结果顺着原Promise链路传回调用组件 return $axios.request(error.config) }) } // 其余错误正常抛出,不做拦截 return Promise.reject(error) })
关键改动点
- 拦截器所有逻辑分支必须显式返回Promise,不能在拦截器内部吞掉异步请求结果
- 增加
_isRetried自定义标记,防止Token失效场景下反复重试触发死循环 - 必须return重发的请求实例,让重发后的成功/失败结果可以顺着组件最初发起请求的链路,传回组件的
await或者.then回调中,组件拿到数据后就会走正常的赋值逻辑,触发响应式更新。
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

