与客户拦截器一起使用时,Axios catch 不起作用

Axios catch not working when used with a customer interceptor

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

request.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

您需要将第二个参数传递给回调 new Promise,称为 reject,然后使用该函数而不是 Promise.reject 拒绝承诺。

我无法在不进行测试的情况下进行验证,现在设置起来有点困难,但看起来您没有正确拒绝从错误回调中返回的承诺。如果您可以确认承诺在 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 反模式的观点非常好。您无缘无故地创建了一个新的 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

应该是这样的。