Axios拦截器重试发送FormData

问题描述

我正在尝试为包含FormData作为数据的请求创建“重试”功能。 重试发生在JWT令牌过期时,我的第二个请求(重试一个)不包含任何数据。

想法:

const axiosInstance = axios.create();

  /**
   * Before each request,we'll add a possible retry if the
   * request need a refreshed token
   */
  axiosInstance.interceptors.request.use((request) => {
    if (typeof _.get(request,['retried']) === 'undefined') {
      request.retried = false;
    }

    return request;
  });

/**
   * After a request with an error,we'll check if the error is a token not refreshed.
   * If we didn't already tried to refresh,we'll just fallback to the errorHandler function
   */
  axiosInstance.interceptors.response.use(null,async (error) => {
    const statusCode = _.get(error,['response','data','statusCode']);
    const message = _.get(error,'message']);
    const { config: request = {} } = error;

    if (statusCode === 401 && !request.retried) {
      try {
        const newTokens = await refreshTokens();
        request.retried = true;
        _.set(request,['headers','authorization'],newTokens.accesstoken);
        return axiosInstance.request(request);
      } catch (e) {
        return error;
      }
    }
    return error;
  });

请求:

  const formData = new FormData();
  formData.append('name',name);
  formData.append('file',fs.createReadStream(file.path));

  axiosInstance.post(
      'http://localhost/upload',formData,{
        headers: {
          ...formData.getHeaders(),authorization: tokens.accesstoken
        }
      }
    );

如果我的令牌过期,请求将失败,拦截器将刷新我的令牌,并仅使用新的头文件Authorization重试完全相同的请求。但是,在服务器端,接收到的有效载荷始终为空。

解决方法

据我所知,需要在重试中再次添加formData(我认为这是由于数据作为流添加并在请求期间被消耗,因此新的重试无法消耗已经消耗的流)

您可以看看request.data来了解我的意思。

,

您可以在 config 参数中传递表单数据:

axiosInstance.post(
  'http://localhost/upload',{},{
    data: formData,// <---- pass it here
    headers: {
      ...formData.getHeaders(),authorization: tokens.accessToken
    }
  }
);