Q:

xhr caching values from getResponseHeader?

I'm running up against a very frustrating bug. I'm not exactly sure what is happening, but I think xhr is doing some kind of cache on the response headers.
My app is using devise_token_auth for the backend authentication service. We're using it with rotating access-tokens, and so I have written a function that runs after every request.
function storeAndGetResponseHeaders(xhr) {
    const headersObj = {};

    headerKeys.filter((key) => xhr.getResponseHeader(key))
    .forEach((key) => {
        headersObj[key] = xhr.getResponseHeader(key);
        window.sessionStorage.setItem(key, xhr.getResponseHeader(key));
    });

    return headersObj;
}

where headerKeys is ['access-token', 'client', 'expiry', 'uid', 'token-type']. So any response that has these headers it should save them into sessionStorage and then return them in an object which gets stored within my AJAX service that I wrote and added to every request. We're using rxjs, and this service is just a thin wrapper around it. This is what RxAjax.ajax looks like.
ajax(urlOrRequest) {
    const request = typeof urlOrRequest === 'string' ? { url: urlOrRequest } : urlOrRequest;
    request.headers = Object.assign({}, this.headers, urlOrRequest.headers);
    request.url = `${this.baseUrl}${request.url}`;

    return Observable.ajax(request).map(this.afterRequest, this);
}

where this.headers is the stored headers from last request (or the loaded headers from sessionStorage). this.afterRequest is what sets the headers from the response xhr.
My problem is that I'm getting bad values into my headers object (specifically old access tokens). What I've noticed is that when I add a logging statement of headersObj after assignment, sometimes it will have old response headers from a past request. However when I look at the request itself in the dev console Network tab, it doesn't show any of the auth headers in the response headers ('access-token', 'client', etc...). This gets fixed for a little while if I do a hard refresh on the browser, but comes back seemingly inexplicably.
Note we're using rxjs to make our requests, which might be relevant (but I don't think it is the cause of this problem, as I'm trying to read the headers from the original xmlhttprequest object). Thanks!

A:

As Barmar suggested in the comments, it was a caching issue. There may be a bug in the chrome console, where it wasn't showing the cached headers that were on the cached request. Hence even though it looked like there were no auth headers there really were.
It looks like if you're using jQuery you can add the option cache: false to the request in order to prevent caching. Because I'm not, the first thing I did was try adding ?cache=${new Date().toJSON} to each request, which successfully busted the cache and fixed my problem (that is what cache: false in jQuery does).
Our backend is in rails, and so I ended up adding
before_action :set_cache_headers

...

private

def set_cache_headers
  response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate"
end

to my application controller. Now no requests are cached by the browser. Not sure if this will be our long term solution or not

