javascriptreactjsasync-awaitfetch-apisynchronous

Second request is not waiting the first requests response via fetch api in Firefox


I have a very strange behavior in Firefox. The code as you can see below. As soon as the the first request's response returned, the header is enriched and the second request is sent. But I see in server logs that sometimes requests (second request) does not contain a token (custombackendtoken). How can that be?

You can reproduce the problem in firefox by reloading the page. While the page is loading or while the first request is running (via multiple trials of refresh).

The same scenario in chrome does not occur. How can the second request go to the backend without a custombackendtoken header?

I checked also the server logs via header dump and the second request is obviously sent by browser without expected header. order is so: request1 input request2 input request2 output request1 output

I would be very grateful if anyone has an idea.

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

Solution

  • It was firefox cache issue. During the refresh, firefox calls the URL from the cache and also sends the request to the server, at this point 2 requests are called asyncrone, which is why a request ends up in the backend without a header.

    The behavior was not seen in chrome.

    As a solution I appended the current timestamp to the url to skip caching.