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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 10:01:46