第二个请求不会通过 Firefox 中的 fetch api 等待第一个请求响应

问题描述 投票:0回答:1

我在 Firefox 中有一个非常奇怪的行为。 代码如下所示。 一旦第一个请求的响应返回,标头就会被丰富并发送第二个请求。但我在服务器日志中看到有时请求(第二个请求)不包含令牌(custombackendtoken)。怎么会这样?

您可以通过重新加载页面在 Firefox 中重现该问题。当页面加载或第一个请求运行时(通过多次尝试刷新)。

在chrome中不会出现同样的情况。 如果没有custombackendtoken header,第二个请求如何到达后端?

我还通过标头转储检查了服务器日志,第二个请求显然是由浏览器发送的,没有预期的标头。 顺序是这样的: 请求1输入 请求2输入 请求2输出 请求1输出

如果有人有想法,我将非常感激。

export const fetchData = async (input: RequestInfo, options?: RequestInit, proxyPath?: string): Promise<Response> => {
  try {
    // first request
    const bearerToken = await getAuthToken(proxyPath);

    const reqOptions: RequestInit = options || {};
    reqOptions.headers = {
      ...reqOptions.headers,
      custombackendtoken: bearerToken,
    };

    // second request
    return await fetch(input, reqOptions);
  } catch (e) {
    console.error('Error.......', e);
    throw new Error(`Error....... Error: ${e}`);
  }
};


//getAuthToken
export default async (proxyPath: string): Promise<string> => {
  let token = await retrieveStoredToken(proxyPath);
  
  if (!token) {
    token = await createToken();
    if (!token) {
      throw new Error('Token can not be created!');
    }
    storeToken(proxyPath, token);
  }

  return token;
};

//retrieveStoredToken
const retrieveStoredToken = async (proxyPath: string): Promise<string | undefined> => {
  try {
    const response = await fetch(`${proxyPath}/token`, {
      credentials: 'same-origin',
    });

    return await response.json();
  } catch (e) {
    console.error('Error ..........', e);
  }
  return undefined;
};
javascript reactjs async-await fetch-api synchronous
1个回答
0
投票

只是猜测,但它可能与 Firefox 中的一个旧错误有关,该错误导致无法正确处理中止的请求:https://bugzilla.mozilla.org/show_bug.cgi?id=1583815

不幸的是,这个错误已经存在很多年了,而且似乎从未得到修复。

如果此错误是您在服务器日志中看到的偶尔问题的原因,则在此讨论中提供了有关如何解决此问题的提示:https://github.com/Yaffle/EventSource/issues/130 #issuecomment-535862539

基本上,您将在获取数据时提供 AbortController 信号,用它来识别中止的请求,然后处理这种情况:

 var controller = new AbortController();
  var signal = controller.signal;
  fetch('data:text/plain,test', {signal}).then(function(response) {
    if (signal?.aborted) {
      const reader = response.body.getReader();
      reader.cancel();
      // ... handle the aborted request, prevent the follow-up request etc.
    }
  })
© www.soinside.com 2019 - 2024. All rights reserved.