首页 > 解决方案 > 与客户拦截器一起使用时,Axios 捕获不起作用

问题描述

我正在使用拦截器刷新访问令牌的状态代码,401但我catch已停止处理任何其他错误代码,例如400

请求.js

import axios from 'axios'

const axiosApiInstance = axios.create()

axiosApiInstance.interceptors.response.use(
    (response) => {
      return response
    },
    (error) => {
      return new Promise((resolve) => {
        const originalRequest = error.config
        const refreshToken = localStorage.getItem("refresh")
        if (error.response && error.response.status === 401 && error.config && !error.config.__isRetryRequest && refreshToken) {
          originalRequest._retry = true
  
          const response = fetch('http://127.0.0.1:8000/api/token/refresh/', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({
              refresh: refreshToken,
            }),
          })
            .then((res) => res.json())
            .then((res) => {
              localStorage.setItem("access", res.access) 
              originalRequest.headers['Authorization'] = 'Bearer ' + res.access
              return axios(originalRequest)
            })
          resolve(response)
        }
        return Promise.reject(error)
      })
    },
  )

  export default axiosApiInstance

标签: javascriptaxiosinterceptor

解决方案


您需要将第二个参数传递给回调以new Promise调用reject,然后使用该函数而不是Promise.reject.

我无法在没有测试的情况下进行验证,现在设置起来有点困难,但看起来你没有正确拒绝你从错误回调返回的承诺。如果您可以确认在 a 的情况下承诺永远不会被解决或拒绝400,那将有助于证实我的怀疑。不过,请尝试进行此更改:

新 Promise 回调的参数:

      return new Promise((resolve) => {

变成

      return new Promise((resolve, reject) => {

后来拒绝,而不是

        return Promise.reject(error)

就这样做

        reject(error) // return does nothing here, can be omitted

编辑:

虽然,有人说这是一个承诺反模式,这是一个很好的观点。你无缘无故地创建了一个新的 Promise。

import axios from 'axios'

const axiosApiInstance = axios.create()

axiosApiInstance.interceptors.response.use(
    (response) => {
      return response
    },
    (error) => {
        const originalRequest = error.config
        const refreshToken = localStorage.getItem("refresh")
        if (error.response && error.response.status === 401 && error.config && !error.config.__isRetryRequest && refreshToken) {
            originalRequest._retry = true

            return fetch('http://127.0.0.1:8000/api/token/refresh/', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                refresh: refreshToken,
            }),
            })
            .then((res) => res.json())
            .then((res) => {
                localStorage.setItem("access", res.access) 
                originalRequest.headers['Authorization'] = 'Bearer ' + res.access
                return axios(originalRequest)
            })
        }
        return Promise.reject(error)
    },
  )

  export default axiosApiInstance

应该是这样的。


推荐阅读