第一次请求失败并尝试第二次请求时返回响应

sg24os4d  于 2022-09-28  发布在  iOS
关注(0)|答案(1)|浏览(210)

我试图解释这个问题。在App.js中,当调用此函数时,我有函数getUser。在第一个请求中获取401错误。因此,在axios.interceptors.response中我收到错误401。此时,我收到一个令牌,并再次重复我的请求。这是成功的。但不返回函数getUser中的响应。
我有钩子用于身份验证和发送请求。

import React from "react";
import axios from "axios";

const API_URL = "http://127.0.0.1:4000/api/";

function useJWT() {

  axios.interceptors.request.use(
    (request) => {
      request.headers.common["Accept"] = "application/json";
      console.log("request Send ");
      return request;
    },
    (error) => {
      return Promise.reject(error);
    }
  );
  axios.interceptors.response.use(
    (response) => {
      console.log("answer = ", response);
      return response;
    },
    (error) => {
      if (error?.response?.status) {
        switch (error.response.status) {
          case 401:
            refreshToken().then((responseTwo) => {
              return
                sendPostRequest(
                  error.response.config.url
                    .split("/")
                    .findLast((item) => true)
                    .toString(),
                  error.response.config.data
              );
            });
            break;
          case 500:
            // Actions for Error 500
            throw error;
          default:
            console.error("from hook interceptor => ", error);
            throw error;
        }
      } else {
        // Occurs for axios error.message = 'Network Error'
        throw error;
      }
    }
  );

  const refreshToken = () => {
    const token = localStorage.getItem("refresh");
    return axios
      .post(API_URL + "token", {
        token,
      })
      .then((response) => {
        if (response.data.access) {
          localStorage.setItem("access", response.data.access);
        }
        if (response.data.refresh) {
          localStorage.setItem("refresh", response.data.refresh);
        }
        return response.data;
      });
  };

  function login(email, password) {
    return axios
      .post(API_URL + "login", {
        email,
        password,
      })
      .then((response) => {
        if (response.data.access) {
          localStorage.setItem("access", response.data.access);
        }
        if (response.data.refresh) {
          localStorage.setItem("refresh", response.data.refresh);
        }
        return response.data;
      });
  }

  const sendPostRequest = (url, data) => {
    console.log(300);
    const token = localStorage.getItem("access");
    axios.defaults.headers.common["jwt"] = token;

    return axios.post(API_URL + url, {
      data,
    });
  };

  const logout = () => {
    const token = localStorage.getItem("refresh");
    return axios
      .delete(API_URL + "logout", {
        token,
      })
      .then((response) => {
        localStorage.removeItem("access");
        localStorage.removeItem("refresh");
      });
  };

  return {
    login,
    logout,
    refreshToken,
    sendPostRequest,
  };
}

export default useJWT;

在应用程序中。js,如果在读取用户信息时出现401错误,我想再次重复相同的请求。请求成功重复,但未返回值。
当第一个请求失败时,响应为return等于null。在catch中,当收到401错误时,我发送第二个请求,但不返回响应。
我发送以下代码请求。

const getUser = () => {
 console.log(12);
 return sendPostRequest("user");
  };

  useEffect(() => {
    let token = localStorage.getItem("access");
    console.log("token = ", token);
    if (token != null) {
      //Here I have done simulation for 401 error
     localStorage.setItem("access", "");
       getUser()
         .then((response) => {
           console.log("response 1= ", response);
         })
    .catch((exception) => {
      console.log("exception = ", exception.toString());
    })
    .then((response) => {
      console.log("response 2= ", response);
    });
} else {
  navigate("/login");
}
 }, []);

顺致敬意,

amrnrhlw

amrnrhlw1#

我不完全明白你到底想在这里做什么。但是,如果您希望在401发生时重试,可以使用axios-retry为您执行此操作。
我会讲完基础知识,但你可以进一步了解它的作用。

// First you need to create an axios instance
const axiosClient = axios.create({
  baseURL: 'API_URL',
  // not needed
  timeout: 30000
});

// Then you need to add this to the axiosRetry lib
axiosRetry(axiosClient, {
  retries: 3,
  // Doesn't need to be this, it can be a number in ms
  retryDelay: axiosRetry.exponentialDelay,
  retryCondition: (error) => {
  // You could do this way or try to implement your own
    return error.response.status > 400 
    // something like this works too.
    // error.response.status === 401 || error.response.status >= 500;
  }
});

就像在您的代码中一样,如果您想避免破坏页面,我们需要使用拦截器,否则您可以使用e1d1e捕获请求中可能发生的任何错误。

// It could be something like this, like I said, it's not really needed.
axiosClient.interceptors.response.use(
  (success) => success,
  (err) => err
);

最后,您可以直接使用axiosClient,因为它现在有您的API_URL,称它为axiosClient.post('/user')
或多或少,您应该调试这段代码,看看是什么导致返回值为null。我会将这些then/catch更改为async/await函数,它将更具可读性,使调试更容易。
如果你不理解我的解释。

相关问题