2016-12-23 5 views
1

Ich laufe gegen einen sehr frustrierenden Fehler. Ich bin mir nicht ganz sicher, was passiert, aber ich denke, dass xhr eine Art Cache auf den Antwortheadern durchführt.xhr Caching-Werte von getResponseHeader?

Meine App verwendet devise_token_auth für den Back-End-Authentifizierungsdienst. Wir verwenden es mit rotierenden Zugriffstoken, und so habe ich eine Funktion geschrieben, die nach jeder Anfrage ausgeführt wird.

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

wo headerKeys ist ['access-token', 'client', 'expiry', 'uid', 'token-type']. Also jede Antwort, die diese Header hat, sollte sie in sessionStorage speichern und sie dann in einem Objekt zurückgeben, das in meinem AJAX-Dienst gespeichert wird, den ich geschrieben und jeder Anfrage hinzugefügt habe. Wir verwenden rxjs, und dieser Service ist nur ein dünner Wrapper um ihn herum. So sieht RxAjax.ajax aus.

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

wo this.headers die gespeicherten Headern von den letzten Anforderung (oder der geladenen Header von session). this.afterRequest setzt die Header aus der Antwort xhr.

Mein Problem ist, dass ich schlechte Werte in meine Header-Objekte (speziell alte Zugriffstoken) bekomme. Was ich bemerkt habe ist, dass wenn ich nach der Zuweisung eine Logging-Anweisung von headersObj hinzufüge, manchmal alte Antwort-Header von einer früheren Anfrage haben. Wenn ich jedoch die Anfrage selbst auf der Registerkarte Netzwerk der Entwicklungskonsole anschaue, zeigt sie keine der Auth-Header in den Antwortheadern ('access-token', 'client', etc ...). Dies wird für eine Weile behoben, wenn ich eine harte Aktualisierung im Browser mache, aber scheinbar unerklärlich zurückkommt.

Hinweis wir rxjs verwenden unsere Wünsche zu machen, die relevant sein könnten (aber ich glaube nicht, dass die Ursache für dieses Problem ist, wie ich die Header aus dem ursprünglichen xmlhttprequest Objekt zu lesen, ich versucht). Vielen Dank!

+2

Sind Sie sicher, dass es die Anfrage überhaupt sendet und nicht nur die zwischengespeicherte Antwort verwendet? Versuchen Sie, der URL einen Cache-Buster hinzuzufügen. – Barmar

+0

Sie haben Recht! Vielen Dank! Am Ende stellte ich response.headers ["Cache-Control"] = "no-cache, no-store, muss-revalidate" (in rails) bei jeder Anfrage ein. Fühlen Sie sich frei, die Frage zu beantworten, damit ich akzeptieren kann! –

+0

Ich kenne keine Schienen. Sie können Ihre eigene Frage beantworten. – Barmar

Antwort

1

Wie Barmar in den Kommentaren vorgeschlagen hat, war es ein Caching-Problem. Es könnte einen Fehler in der Chrome-Konsole geben, in dem die zwischengespeicherten Header, die sich auf der zwischengespeicherten Anfrage befanden, nicht angezeigt wurden. Obwohl es so aussah, als gäbe es keine Auth-Header, gab es wirklich.

Es sieht so aus, als ob Sie jQuery verwenden, können Sie die Option cache: false der Anfrage hinzufügen, um das Zwischenspeichern zu verhindern. Weil ich nicht bin, war das erste, was ich tat, zu versuchen, ?cache=${new Date().toJSON} zu jeder Anfrage hinzuzufügen, die erfolgreich den Cache brach und mein Problem reparierte (das ist, was cache: false in jQuery tut).

Unser Backend ist in Schienen, und so landete ich Aufsummierung

before_action :set_cache_headers 

... 

private 

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

meiner Anwendungssteuerung. Jetzt werden keine Anfragen vom Browser zwischengespeichert. Nicht sicher, ob dies unsere langfristige Lösung ist oder nicht