HTTP-Cache-Control-Header Was no-cache, no-store und max-age tatsächlich bedeuten
Ein praktischer Überblick zu Cache-Control-Anweisungen — was Browser und CDNs tatsächlich mit no-cache, no-store, max-age, s-maxage und ETags tun. Einschließlich der Fehler, die die meisten Entwickler in der Produktion treffen.
Sie haben wahrscheinlich geschrieben Cache-Control: no-cache und angenommen, dass der Browser die Cache-Datei komplett überspringt. Das wird nicht geschehen. no-cache bedeutet „neu validieren, bevor aus dem Cache geliefert wird“. Wenn Sie tatsächlich wollen, dass die Antwort nie gespeichert wird, dann ist das no-store. Diese Verwirrung verursacht in der Produktion alte Datenfehler, die schwer zu diagnostizieren sind, weil alles in der Network-Option beim ersten Laden normal aussieht.
Lassen Sie uns jede Richtlinie klar durchgehen — was Browser damit tun, was CDNs damit tun, und welche Fehler entstehen, wenn sie vermischt werden.
Die vollständige Referenz zu Cache-Control-Richtlinien
| Richtlinie | Verhalten des Browsers | Verhalten von CDN / Proxy | Typische Anwendung |
|---|---|---|---|
max-age=N | Cache für N Sekunden | Cache für N Sekunden (außer s-maxage überschreibt) | Statische Assets, API-Antworten |
s-maxage=N | Ignoriert | Cache für N Sekunden | CDN-TTL getrennt vom Browser |
no-cache | Cache, aber jedes Mal neu validieren | Cache, aber jedes Mal neu validieren | Häufig wechselnde Inhalte mit ETags |
no-store | Nicht speichern | Nicht speichern | Auth-Antworten, sensible Benutzerdaten |
must-revalidate | Keine veraltete Auslieferung — neu validieren oder fehlschlagen | Keine veraltete Auslieferung — neu validieren oder fehlschlagen | API-Antworten, bei denen veraltete Daten funktionell falsch sind |
proxy-revalidate | Ignoriert | Keine veraltete Auslieferung bei gemeinsamen Caches | CDN-spezifische „must-revalidate“ |
private | Der Browser kann cacheen | Muss nicht cacheen | Benutzer-spezifische Seiten |
public | Jeder Cache kann speichern | Kann cacheen | Gemeinsame statische Ressourcen |
immutable | Keine Validierung innerhalb von max-age | Variiert je nach CDN | Gekürzte / versionierte Assets |
stale-while-revalidate=N | Veraltetes Angebot für N Sekunden während Abruf der frischen Version | Variiert je nach CDN | Geschwindigkeit ohne starke Veraltungen |
max-age und s-maxage: Browser vs. CDN-TTL
max-age=N gibt sowohl dem Browser als auch den CDNs an, wie viele Sekunden die Antwort frisch ist. Nach N Sekunden ist die gespeicherte Antwort veraltet und muss vor der Nutzung neu validiert werden.
s-maxage=N ist CDN-spezifisch. Browser ignorieren es völlig. Wenn Sie möchten, dass ein CDN eine Stunde lang cacheiert, aber der Browser nur 5 Minuten lang:
Cache-Control: max-age=300, s-maxage=3600
Der Browser cacheiert für 5 Minuten. CloudFront, Fastly, Nginx — sie verwenden 3600 Sekunden. Ein häufiger Fehler: die Einstellung von max-age=0 denken, dass sie das Caching deaktiviert. Das ist nicht der Fall. max-age=0 bedeutet, dass die Antwort sofort veraltet ist — der Browser speichert sie weiter und validiert sie, wobei wahrscheinlich ein 304 zurückgegeben wird. Wenn Sie die Cache-Verwendung nicht wollen, verwenden Sie no-store.
no-cache: Nicht das, was Sie denken
Cache-Control: no-cache bedeutet nicht „keine Verwendung des Caches“. Es bedeutet „keine Auslieferung aus dem Cache ohne vorherige Validierung beim Server“.
Die Sequenz, wenn ein Browser eine gespeicherte Antwort mit no-cache:
- empfängt
- Ein neuer Antrag für die gespeicherte Ressource
If-None-MatchDer Browser sendet die ETag (über - ) oder den Last-Modified-Timestamp an den Server
304 Not ModifiedWenn der Inhalt unverändert ist → der Server gibt - mit keinem Körper zurück
200 OKWenn der Inhalt geändert wurde → der Server gibt
mit der neuen Antwort zurück no-storeim Vergleich zu no-cache : Sie erhalten weiterhin die Bandbreitenersparnis von 304-Antworten. Wenn Ihr Inhalt gelegentlich geändert wird, aber bei Änderung frisch sein muss,
in Kombination mit einem ETag ist die richtige Kombination.
Cache-Control: no-store no-store: Der echte „Kein Caching“
bedeutet, dass die Antwort nirgendwo gespeichert werden darf — weder im Browser-Cache, noch in einem CDN, noch in einem Zwischenspeicher. Keine Kopie, vollständig.
- Verwenden Sie dies für:
- Authentifizierungsantworten (Login-Tokens, Sitzungsdaten)
- Sensible persönliche Daten
Einmalige Inhalte (Zahlungsbestätigungen, OTP-Seiten) no-store Ein kleiner Nuance: pageshow verhindert nicht, dass eine Seite im Browser-Back-Forward-Cache (bfcache) erscheint. Browser speichern einen in-Memory-Snapshot für die Leistung bei Navigation, der getrennt vom HTTP-Cache ist. Wenn Sie Probleme mit dem Back-Button nach Abmelden haben, verbinden Sie sich mit dem event.persisted.
Event und prüfen
must-revalidate: Keine veraltete Flexibilität must-revalidate erlaubt die HTTP-Caching-Spezifikation, dass Caches veraltete Antworten liefern, wenn die Quelle nicht erreichbar ist — eine Resilienz-Funktion, die die meisten Entwickler nicht kennen.
# Without must-revalidate: CDN may serve stale if origin is slow or down
Cache-Control: max-age=3600
# With must-revalidate: stale = error, not a fallback
Cache-Control: max-age=3600, must-revalidate
entfernt diese Flexibilität: sobald eine gespeicherte Antwort veraltet ist, muss der Cache neu validiert werden oder eine 504 zurückgeben. Es gibt unter keinen Umständen veraltete Auslieferung.
Verwenden Sie dies für API-Antworten, bei denen veraltete Daten die Funktionalität brechen — wie Bestandteile, Preise, Auth-Status — anstatt nur leicht falsch auszusehen.
private private vs public: Der CDN-Fehler, der sensible Daten enthüllt
public bedeutet, dass die Antwort für einen bestimmten Benutzer bestimmt ist. Browser können sie cacheen; gemeinsame Caches (CDNs, Reverse-Proxies) dürfen sie nicht. public.
erlaubt jedem Cache — einschließlich gemeinsamer —, die Antwort zu speichern. Einige Caches speichern nur authentifizierte Anfragen, wenn Sie explizit markieren Cache-Control: public, max-age=3600 Der echte Weltfehler, den dies verursacht: Ein Entwickler kopiert private von einem statischen Asset auf eine Seite, die benutzerbezogene Daten enthält. Der CDN speichert die Antwort. Benutzer B macht die gleiche Anfrage und erhält die Seite von Benutzer A aus dem Cache. Das ist nicht theoretisch — GitHub hatte eine Variante davon im Jahr 2018. Markieren Sie authentifizierte oder benutzerbezogene Antworten
explizit, selbst wenn Sie denken, dass Ihr CDN „wissen“ soll, dass es sie nicht speichern soll.
ETags sind die Weise, wie der Server sagt „hier ist ein Fingerabdruck dieser Antwort“. Der Browser speichert die ETag neben der gespeicherten Antwort und sendet sie beim nächsten Antrag über If-None-Matchzurück. Wenn der Inhalt nicht geändert wurde, gibt der Server 304 Not Modified mit keinem Körper zurück — genauso wie die Frische-Enforcement von no-cache, viel weniger Bandbreite.
Der no-cache + ETag-Fluss:
→ GET /api/config HTTP/1.1
← HTTP/1.1 200 OK
Cache-Control: no-cache
ETag: "abc123"
[full response body]
→ GET /api/config HTTP/1.1
If-None-Match: "abc123"
← HTTP/1.1 304 Not Modified
[no body — browser uses its cached copy]
Zwei Arten von ETags:
- Starke ETags (
"abc123") — byte-für-byte identisch. Erforderlich für die Unterstützung von Range-Anfragen durch CDNs. - Schwache ETags (
W/"abc123") — semantisch äquivalent, aber nicht notwendigerweise byte-identisch. Gut für Browser-Validierung, nicht für Range-Anfragen.
Nginx generiert ETags automatisch aus der Datei-Mtime und der Größe. Express fügt sie standardmäßig nicht hinzu — verwenden Sie app.set('etag', 'strong') oder die etag Middleware explizit.
Last-Modified und If-Modified-Since
Das gleiche Konzept wie ETags, aber grob — basierend auf einem Zeitstempel anstatt auf einem Inhalt-Hash. Der Server enthält Last-Modified; der Browser sendet If-Modified-Since auf folgenden Anfragen.
Das Problem: Wenn Sie neu bereitstellen und die Datei-Modifikationszeiten aktualisiert werden, obwohl der Inhalt nicht geändert wurde, werden die Caches unnötigerweise ungültig. Ein Inhalt-Hash-basierter ETag hat dieses Problem nicht. Verwenden Sie ETags, wenn möglich, und behandeln Sie Last-Modified als eine Rückkehr für Server, die keine ETags unterstützen.
Vary: Der Header, der Ihr Cache schweigend vervielfacht
Der Vary Header sagt den Caches, dass die Antwort je nach anderen Anfrage-Header variieren kann. Jede einzigartige Kombination dieser Header erhält eine eigene Cache-Entscheidung.
Vary: Accept-Encoding
Das sagt den Caches, dass sie getrennte Antworten für gzip, brotli und Identität speichern. Richtig und häufig. Der gefährliche Punkt: Vary: Cookie. Jeder Benutzer hat eine einzigartige Cookie-Set, daher erhält jeder Benutzer eine eigene Cache-Entscheidung — effektiv deaktiviert die gemeinsame Cache-Funktion. Viele Frameworks fügen Vary: Cookie silently hinzu. Wenn Ihr CDN-Cache-Hit-Rate unerklärlich niedrig ist, obwohl Sie große max-age Werte haben, prüfen Sie Ihre Antwort-Header auf Vary: Cookie die aus dem Session-Middleware schlüpfen.
Vary: * bedeutet im Prinzip „kein Caching“ — jede Anfrage wird als einzigartig behandelt. Es ist äquivalent zu no-store für CDNs.
Cache-Busting mit Query-Parametern
Wenn Sie eine frische Download von versionierten Assets erzwingen müssen, ist die Standardmethode, einen Query-Parameter anzuhängen — der Query-String ist Teil der URL, daher wird er als neuer Ressource sowohl vom Browser als auch von CDNs behandelt:
/app.js?v=2.1.4
/styles.css?hash=a1b2c3d4e5f6
Wenn Sie dynamisch Cache-Busting-Parameter aus Inhalt-Hashes oder Version-Strings erstellen, die Sonderzeichen enthalten, stellen Sie sicher, dass sie vor dem Hinzufügen percent-gekodiert werden. Der URL-Kodierer/Dekodierer behandelt das schnell, wenn Sie URLs manuell testen oder erstellen.
Die drei Fehler, die die meisten Entwickler treffen
1. Verwenden von no-cache, wenn Sie no-store meinen. Wenn Sie Auth-Response, Logout-Endpunkte oder alles mit PII verarbeiten, möchten Sie no-store. no-cache lässt Daten im Browser-Cache (nur als veraltet markiert); no-store entfernt die Spur vollständig. Der Unterschied spielt eine Rolle, wenn Benutzer Geräte teilen.
2. Keine Einstellung von s-maxage für CDN-Steuerung. Ohne s-maxageverwendet Ihr CDN max-age. Wenn max-age kurz ist (z. B. 60 Sekunden), dann speichert Ihr CDN auch 60 Sekunden — was wahrscheinlich nicht Ihr Wunsch ist. Trennen Sie die beiden TTLs explizit.
3. public auf Endpunkten, die benutzerbezogene Daten zurückgeben. Dieser Punkt ist ein Sicherheitsvorfall, nicht nur ein Leistungsproblem. Jede Antwort, die personalisiert oder authentifiziert ist, sollte privatesein. Standardmäßig auf private und nur für wirklich gemeinsame Ressourcen auf public setzen.
Alles zusammenführen
Das mentale Modell: no-cache bezieht sich auf die Frische-Enforcement — die Antwort lebt im Cache, sie benötigt nur eine Server-Prüfung, bevor sie verwendet wird. no-store bezieht sich auf das vollständige Verschwinden. max-age ist Ihr Browser-TTL. s-maxage ist Ihr CDN-TTL. ETags machen die Validierung günstig.
Halten Sie die private/public Unterscheidung richtig auf jedem Endpunkt, der Benutzerdaten berührt. Dieser einzige Fehler — die Kopie eines Cache-Headers von einem statischen Asset auf einen authentifizierten Endpunkt — führt zu einem Querschaltungsdatenleak, wenn Ihr CDN personalisierte Antworten speichert.
Erweiterungen installieren
IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche
恵 Die Anzeigetafel ist eingetroffen!
Anzeigetafel ist eine unterhaltsame Möglichkeit, Ihre Spiele zu verfolgen. Alle Daten werden in Ihrem Browser gespeichert. Weitere Funktionen folgen in Kürze!
Unverzichtbare Tools
Alle Neuheiten
AlleAktualisieren: Unser neuestes Werkzeug wurde am 20. Juni 2026 hinzugefügt
