NodeJS / express: Cache und 304 Statuscode

91

Wenn ich eine mit Express erstellte Website neu lade, wird mit Safari (nicht mit Chrome) eine leere Seite angezeigt, da mir der NodeJS-Server einen 304-Statuscode sendet.

Wie kann man das lösen?

Natürlich könnte dies auch nur ein Problem von Safari sein, aber tatsächlich funktioniert es auf allen anderen Websites einwandfrei, so dass es auch auf meinem NodeJS-Server ein Problem sein muss.

Um die Seiten zu generieren, verwende ich Jade mit res.render.

Update: Es scheint, dass dieses Problem auftritt, weil Safari 'cache-control': 'max-age=0'beim Neuladen sendet .

Update 2: Ich habe jetzt eine Problemumgehung, aber gibt es eine bessere Lösung? Problemumgehung:

app.get('/:language(' + content.languageSelector + ')/:page', function (req, res)
{
    // Disable caching for content files
    res.header("Cache-Control", "no-cache, no-store, must-revalidate");
    res.header("Pragma", "no-cache");
    res.header("Expires", 0);

    // rendering stuff here…
}

Update 3: Der vollständige Codeteil lautet derzeit:

app.get('/:language(' + content.languageSelector + ')/:page', pageHandle);

function pageHandle (req, res)
{
    var language = req.params.language;
    var thisPage = content.getPage(req.params.page, language);

    if (thisPage)
    {
        // Disable caching for content files
        res.header("Cache-Control", "no-cache, no-store, must-revalidate");
        res.header("Pragma", "no-cache");
        res.header("Expires", 0);

        res.render(thisPage.file + '_' + language, {
            thisPage : thisPage,
            language: language,
            languages: content.languages,
            navigation: content.navigation,
            footerNavigation: content.footerNavigation,
            currentYear: new Date().getFullYear()
        });
    }
    else
    {
        error404Handling(req, res);
    }
}
h345k34cr
quelle
1
304 ist kein Problem. Dies bedeutet lediglich, dass Ihre Antwort nicht geändert wird und Ihr Browser zum Abrufen der Ressource in den Cache wechselt. Können Sie den relevanten Code veröffentlichen, in dem eine Anomalie auftritt?
Akshat Jiwan Sharma
3
Ja, eigentlich wird es nicht geändert, aber Safari leert seinen Cache auf CMD + R (Reload) und der Server sagt nur, dass es sich nicht geändert hat.
h345k34cr
Wie hängt die leere Seite mit dem 304-Statuscode zusammen? Der Knoten würde 304 auch an andere Browser senden.
user568109
2
Es ist verwandt, weil mit 304 der Körper nicht gesendet wird und der Browser seinen Cache verwendet, aber da es keinen Cache gibt, erhalten Sie eine leere Seite
h345k34cr
Update 2 mit manuell festgelegten Headern zum Deaktivieren des Caching half, das Problem zu beheben.
Nik Sumeiko

Antworten:

105

Einfachste Lösung:

app.disable('etag');

Alternative Lösung hier, wenn Sie mehr Kontrolle wünschen:

http://vlasenko.org/2011/10/12/expressconnect-static-set-last-modified-to-now-to-avoid-304-not-modified/

mischte
quelle
2
Können Sie die "einfachste Lösung" erläutern oder einen Hinweis darauf geben, wie sich dies auswirkt?
Samuel Méndez
1
@ SamuelMéndez es deaktiviert im Grunde das Caching, das Wiki auf etag hat viele gute Infos en.wikipedia.org/wiki/HTTP_ETag
Blented
Arbeitete für mich :)
Naveen Kumar V
3

Wie Sie sagten, sendet Safari Cache-Control: max-age=0beim Nachladen. Express (oder genauer gesagt die Abhängigkeit von Express, knotenfrisch) berücksichtigt den Cache als veraltet, wenn Cache-Control: no-cacheHeader empfangen werden, tut dies jedoch nicht für Cache-Control: max-age=0. Soweit ich das beurteilen kann, sollte es wahrscheinlich so sein. Aber ich bin kein Experte für Caching.

Das Update besteht darin, die Zeile 37 von node-fresh/index.jsvon (was aktuell ist) zu ändern

if (cc && cc.indexOf('no-cache') !== -1) return false;  

zu

if (cc && (cc.indexOf('no-cache') !== -1 ||
  cc.indexOf('max-age=0') !== -1)) return false;

Ich habe Node-Fresh und Express gegabelt, um diesen Fix in die package.jsonVia meines Projekts aufzunehmen npm. Sie könnten das Gleiche tun. Hier sind meine Gabeln zum Beispiel:

https://github.com/stratusdata/node-fresh https://github.com/stratusdata/express#safari-reload-fix

Der Zweig safari-reload-fix basiert auf dem Tag 3.4.7.

James P. Javery
quelle
Gute Arbeit! Ich sehe, dass Express 3.5.1 Ihren Fix über Node-Fresh 0.2.2 enthält.
Clafou
Eigentlich irre ich mich, dein Fix wurde zurückgesetzt und hat es nicht auf 0.2.2 geschafft. Immer noch kein Fresh / Express Fix.
Clafou
2

Ich hatte das gleiche Problem in Safari und Chrome (die einzigen, die ich getestet habe), aber ich habe nur etwas getan, das zu funktionieren scheint. Zumindest konnte ich das Problem nicht reproduzieren, seit ich die Lösung hinzugefügt habe. Ich habe dem Header ein Metatag mit einem generierten Zeitstempel hinzugefügt. Scheint nicht richtig, aber es ist einfach :)

<meta name="304workaround" content="2013-10-24 21:17:23">

Update PS Soweit ich das beurteilen kann, verschwindet das Problem , wenn ich meinen Knoten Proxy entfernen (durch Proxy - i sowohl express.vhost bedeuten und http-Proxy - Modul), das ist seltsam ...

user907567
quelle
Ich benutze auch einen Apache-Proxy, dies könnte das Problem sein. Meine Problemumgehung bestand darin, das Caching für Inhaltsseiten mit http-Headern zu deaktivieren.
h345k34cr
Das Deaktivieren des Cache über die Header ist definitiv der richtige Weg. Anfangs hat es bei mir nicht funktioniert, jetzt aber. Mit anderen Worten, ich muss beim ersten Mal irgendwo einen Fehler gemacht haben :)
user907567
1

Versuchen Sie, in Safari privat zu surfen oder Ihren gesamten Cache / Ihre gesamten Cookies zu löschen.

Ich hatte einige ähnliche Probleme mit Chrome, als der Browser dachte, die Website sei im Cache, aber tatsächlich nicht.

Der Teil der http-Anfrage, der den Server dazu bringt, auf 304 zu antworten, ist das etag. Anscheinend sendet Safari das richtige Etag, ohne den entsprechenden Cache zu haben.

sbugert
quelle
Das funktioniert für mich, als ich versucht habe, den gesamten Cache zu löschen, danke
Yuttanant Suwansiri
0

Alte Frage, ich weiß. Das Deaktivieren der Cache-Funktion ist nicht erforderlich und nicht der beste Weg, um das Problem zu verwalten. Durch Deaktivieren der Cache-Funktion muss der Server härter arbeiten und generiert mehr Datenverkehr. Auch der Browser und das Gerät müssen härter arbeiten, insbesondere auf Mobilgeräten kann dies ein Problem sein.

Die leere Seite kann einfach mit der Umschalttaste + der Schaltfläche zum erneuten Laden im Browser gelöst werden.

Die leere Seite kann ein Ergebnis sein von:

  • ein Fehler in Ihrem Code
  • Beim Testen haben Sie eine leere Seite (an die Sie sich nicht erinnern können) bereitgestellt, die vom Browser zwischengespeichert wird
  • ein Fehler in Safari (wenn ja, melden Sie ihn bitte Apple und versuchen Sie nicht, ihn selbst zu beheben)

Versuchen Sie zuerst die Umschalttaste + Taste zum erneuten Laden, um festzustellen, ob das Problem weiterhin besteht, und überprüfen Sie Ihren Code.

Codebeat
quelle