skip to Main Content

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

2

Answers


  1. Chosen as BEST ANSWER

    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.


  2. Just a guess, but it might be related to an old bug in Firefox which results in aborted requests not being handled correctly: https://bugzilla.mozilla.org/show_bug.cgi?id=1583815

    Unfortunately, this bug is open for many years and seems to never get fixed.

    If this bug should be the cause for the occasional problems you see in your server logs, there is a hint about how to work around this problem in this discussion: https://github.com/Yaffle/EventSource/issues/130#issuecomment-535862539

    Basically, you would provide an AbortController signal when fetching data, use it to identify an aborted request and then handle the situation:

     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.
        }
      })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search