简体   繁体   English

Axios 拦截器重试发送FormData

[英]Axios interceptor to retry sending FormData

I'm trying to create a "retry" functionality for a request containing a FormData as data.我正在尝试为包含FormData作为数据的请求创建“重试”功能。 The retry happen when the JWT token is expired, my second request (the retry one) doesn't contain any data.重试发生在 JWT 令牌过期时,我的第二个请求(重试请求)不包含任何数据。

The idea:想法:

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, ['response', 'data', '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;
  });

The request:要求:

  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
        }
      }
    );

If my token expired, the request will fail, the interceptor will then refresh my tokens, and retry the exact same request with just the new header Authorization .如果我的令牌过期,请求将失败,然后拦截器将刷新我的令牌,并仅使用新的 header Authorization重试完全相同的请求。 Yet, on the server side, the received payload is always null.然而,在服务器端,接收到的负载始终是 null。

As far as I know, the formData needs to be added again on the retry (I think it is due to the data being added as a stream and consumed during the request, so a new retry cannot consume the already consumed stream).据我所知,重试时需要再次添加 formData(我认为这是由于数据被添加为 stream 并在请求期间被消耗,因此新的重试无法消耗已经消耗的流)。

You can take a look at request.data to see what I mean.您可以查看request.data以了解我的意思。

You can pass the form data within the config parameter:您可以在配置参数中传递表单数据:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM