Keine Werbung mögen? Gehen Werbefrei Heute

localStorage vs sessionStorage vs IndexedDB vs Cookies — Browser-Speicher ohne das 3am-Verdruss

Aktualisiert am

Ein praktischer Leitfaden zum Auswählen des richtigen Browser-Speichers — mit einem Vergleichstabelle, der JWT-Debatte klar erklärt und den spezifischen Weisen, wie jede Option Ihr Nachtverhalten ruinieren wird.

localStorage vs sessionStorage vs IndexedDB vs Cookies — Browser Storage Without the 3am Regret 1
ANZEIGE Entfernen?

It’s 3am 😬. A user filed a bug: their shopping cart is empty. You open DevTools, click the Application tab, and stare at the sidebar. Wo haben Sie es hingesetzt? Die richtige Antwort hängt von einer Handvoll Fragen ab, die die meisten Entwickler erst nach dem Eintragen des Fehlers in Betracht ziehen.

Dies ist kein Artikel mit Definitionen. Solche Artikel finden Sie überall. Dies ist der Teil, in dem wir erklären, was kaputt geht, was tatsächlich verwendet werden sollte, und warum die Debatte über JWT in der lokalen Speicherung den Kern der Sache verfehlt.

Die kurze Version (a.k.a. die Tabelle, die Sie sich bookmarken werden)

localStoragesessionStorageIndexedDBDieses Portal verwendet Cookies zur Optimierung der Browserfunktion. Informieren Sie sich, wie wir Cookies verwenden und wie Sie Ihre Einstellungen ändern können.
PersistenceDauerhaftTab-Sitzung nurDauerhaftKonfigurierbar (Sitzung oder Ablaufdatum)
Maximale Größe5–10 MB5–10 MBGB (Browser-Quota)ca. 4 KB pro Cookie
ServerzugriffNEINNEINNEINJa — wird mit jeder Anfrage gesendet
Async-APINein (blockiert die Hauptthread)Nein (blockiert die Hauptthread)Ja (basierend auf Promise/Event)NEIN
JS lesbarJaJaJaNur ohne HttpOnly-Flag
WebWorker-ZugriffNEINNEINJaNEIN
Teilweise über Tabs geteiltJaNein — jeder Tab ist isoliertJaJa
Safari ITP-EntfernungNach 7 Tagen ohne InteraktionBeim Schließen der TabNach 7 Tagen ohne InteraktionAbhängig vom Ablaufattribut

localStorage

Dauerhaft, synchron, origin-spezifisch. Das Arbeitspferd, das jeder erreicht, und die Hälfte der Zeit nicht sollte.

Was es tatsächlich ist

localStorage speichert Zeichenketten als Schlüssel-Wert-Paare. Das ist alles. Die Speichergrenze beträgt in den meisten Browsern 5 MB, in einigen 10 MB (Chrome gibt Ihnen mehr). Es ist auf den Ursprung beschränkt — Protokoll + Domain + Port — also http://example.com und https://example.com haben getrennte Speicher. Es überlebt das Schließen der Tab, den Browserstart, alles außer dem, was der Benutzer ihre Browserdaten löscht oder Sie explizit aufruft localStorage.clear().

// Read/write is synchronous — it happens right now, on the main thread
localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme'); // 'dark'

// Storing objects? You're serializing manually.
localStorage.setItem('user', JSON.stringify({ id: 1, name: 'Alex' }));
const user = JSON.parse(localStorage.getItem('user'));

Wo es versagt

  • Quota überschritten — wirft eine synchrone DOMException: QuotaExceededError. Wenn Sie keine try/catch-Ausführung bei Schreibvorgängen verwenden, werden Sie über einen Benutzerbericht erfahren.
  • Private/Incognito — Browser bieten Ihnen einen frischen, isolierten localStorage mit einer strengeren (oder null) Quota. Firefox hat historisch sofort Quotafehler geworfen. Verlassen Sie nie den localStorage, ohne ihn zu erkennen.
  • Safari ITP — Wenn ein Benutzer Ihre Seite in 7 Tagen nicht besucht, kann Safari localStorage löschen. Dieses Verhalten ist dokumentiert. Es wird Sie am schlechtesten überraschen.
  • XSS — Jedes, was in localStorage gespeichert ist, ist lesbar für jedes JavaScript, das auf Ihrem Ursprung läuft. Wenn ein Angreifer ein Skript einfügt, erhält er alles.

Verwenden Sie es für

UI-Präferenzen (Dunkelmodus, Seitenleistenzustand, Sprache), nicht sensible Caching (letzter abgerufener Zeitstempel, statische Konfiguration), alles, was nach einem Seitenwechsel bestehen sollte, aber keine Authentifizierungstoken oder PII enthält. Wenn Sie darüber nachdenken, ein JWT oder ein API-Schlüssel hier zu speichern — lesen Sie weiter.

sessionStorage

Alles, was localStorage tut, aber mit einer kürzeren Haltbarkeit und einem entscheidenden Isolierverhalten, das Menschen ständig treffen.

Der Tab-Isolierung-Trap

sessionStorage ist pro-Tab, nicht pro-Browser. Wenn die gleiche Seite in einem neuen Tab geöffnet wird, erhalten Sie einen völlig separaten sessionStorage. Dies ist nicht offensichtlich für Benutzer, und es wird Ihnen nicht offensichtlich sein, bis jemand einen Fehler meldet, dass ihre mehrstufige Formulardaten beim „Zufälligen“ Öffnen eines zweiten Tabs verschwinden.

Die einzige Ausnahme: Wenn der Benutzer einen neuen Tab über window.open() oder mittels Klick auf einen Link öffnet, erhält der neue Tab eine Kopie des Parent-SessionStorage zum Zeitpunkt der Öffnung. Danach sind die beiden isoliert. Dies ist die Art von Randfall, die eine großartige Stack Overflow-Frage um 2 Uhr morgens erzeugt.

// Perfect for checkout flows — step data lives until the tab closes
sessionStorage.setItem('checkoutStep', '2');
sessionStorage.setItem('cartSnapshot', JSON.stringify(cart));

// Cleared automatically when the tab closes — no cleanup code needed

Verwenden Sie es für

Mehrstufige Formulardaten, Daten für ein einmaliges Wizard, alles, was für eine Sitzung existieren soll und beim Schließen des Tabs verschwindet. Es ist legitim nützlich für Checkout-Flows — Sie möchten keine teilweise Checkout-Zustände aus einer früheren Sitzung hängen. Verwenden Sie es nicht, wenn Sie Daten zwischen Tabs oder unabhängig geöffneten Seiten teilen müssen.

IndexedDB

Die erwachsene Option. Async, transaktional und in der Lage, tatsächliche JavaScript-Objekte zu speichern — nicht nur serialisierte Zeichenketten. Außerdem verfügt es über die schmerzhafteste native API der drei, weshalb fast niemand sie direkt verwendet.

Was es tatsächlich ist

IndexedDB ist ein vollständiger Schlüssel-Wert-Speicher mit Unterstützung für Indizes und Cursor-basierte Abfragen. Die Speicherbegrenzungen sind großzügig — Browser erlauben einen Prozentsatz des Diskplatzes, in der Praxis meistens Gigabyte. Sie können strukturierte Objekte, Blobs, ArrayBuffers und Dateien ohne manuelle Serialisierung speichern. Es ist in WebWorkers verfügbar. Es ist das, was PWAs und offline-fähige Apps verwenden, um Daten zu speichern, die in der Speicherung nicht in der Speicherung möglich wären.

// Native IDB API — nobody writes this directly in production
const request = indexedDB.open('myDB', 1);
request.onupgradeneeded = (event) => {
  const db = event.target.result;
  db.createObjectStore('users', { keyPath: 'id' });
};
request.onsuccess = (event) => {
  const db = event.target.result;
  const tx = db.transaction('users', 'readwrite');
  const store = tx.objectStore('users');
  store.put({ id: 1, name: 'Alex', avatar: someBlob });
};

// What you actually use — Dexie.js or the idb wrapper
import Dexie from 'dexie';
const db = new Dexie('myApp');
db.version(1).stores({ users: '++id, name, email' });
await db.users.add({ name: 'Alex', email: 'alex@example.com' });

Wo es versagt

  • Safari ITP — genauso wie localStorage: nach 7 Tagen ohne Interaktion kann Safari IndexedDB-Daten löschen. Dies hat mehrere PWAs vor Apple gefährdet, als Apple das Verhalten in neueren iOS-Versionen behoben hat. Wenn Ihr Zielpublikum iOS-Safari-Nutzer enthält, berücksichtigen Sie dies.
  • iOS-geringer Speicherplatz — Auf iOS kann das Betriebssystem IndexedDB-Daten löschen, wenn der Speicherplatz gering ist. Es fragt nicht. Die Daten sind einfach nicht mehr da.
  • Private Browsing — Chrome erlaubt IndexedDB in Incognito (mit einem pro-Sitzungs-Quota). Safari in privater Browsing hatte früher Fehler; das Verhalten variiert je nach Version.
  • Die native API — Wenn Sie raw IDB-Code ohne Wrapper schreiben, wird das auf Callback-basierte Ereignismodell Fehler erzeugen, die Sie ein ganzen Abend lang debuggen müssen. Verwenden Sie idb oder Dexie.js.

Verwenden Sie es für

Offline-Apps, große Datensätze, die localStorage überlasten würden, alles, was Sie sonst auf localStorage aufbauen würden, das die 5 MB-Grenze häufig überschreitet, Dateikachelung in PWAs. Wenn Sie 50 benutzererstellte Dokumente lokal speichern, ist IndexedDB die Lösung. Wenn Sie die Benutzersprachpräferenz speichern, ist es übertrieben.

Dieses Portal verwendet Cookies zur Optimierung der Browserfunktion. Informieren Sie sich, wie wir Cookies verwenden und wie Sie Ihre Einstellungen ändern können.

Das älteste der vier. Das Einzige, das der Server sieht. Das Einzige mit einer 4KB-Grenze, die Sie absolut treffen, wenn Sie versuchen, ein JWT darin zu speichern.

Was Cookies anders macht

Cookies werden automatisch mit jeder passenden HTTP-Anfrage gesendet. Dies ist sowohl die Funktion als auch das Problem. Es bedeutet, dass Ihr Sitzungs-Cookie ohne JavaScript an Ihren Server gelangt — und es bedeutet auch, dass jede Anfrage an api.example.com eine Cookie-Überlastung mitnimmt, egal ob Sie es mögen oder nicht.

Die tatsächlich wichtigen Attribute:

  • verhindert, dass JavaScript das Cookie über — JavaScript kann dieses Cookie nicht lesen. XSS-Angriffe können es nicht exfiltrieren. Dies ist die Grundlage für Sitzungs-Cookies.
  • Sicher — wird nur über HTTPS gesendet. Ohne diese auf einem Produktions-System senden Sie Auth-Cookies über HTTP. Das ist nicht zu empfehlen.
  • SameSite=Strict — das Cookie wird nur gesendet, wenn die Anfrage von Ihrem eigenen Domain ausgeht. Effektive CSRF-Schutz, aber es unterbricht OAuth-Redirect-Flows. SameSite=Lax ist ein vernünftiger Kompromiss für die meisten Anwendungen.
  • Expires / Max-Age — ohne diese wird es ein Sitzungs-Cookie, das beim Schließen des Browsers gelöscht wird. Legen Sie eine explizite Ablaufzeit für „Erinnerung mich“-Verhalten fest.
// Setting a cookie from JavaScript (no HttpOnly, obviously)
document.cookie = "theme=dark; Path=/; Max-Age=31536000; Secure; SameSite=Lax";

// Server-side (Node.js + Express) — where the real power is
res.cookie('sessionId', token, {
  httpOnly: true,   // JS cannot read this
  secure: true,     // HTTPS only
  sameSite: 'lax',  // balanced CSRF protection
  maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days in ms
});

Wenn Sie einen komplizierten Cookie-String debuggen, IO Tools’ Cookie Parser zerlegt es in lesbare Schlüssel-Wert-Paare — nützlich, wenn Sie an einem 400-Zeichen Set-Cookie Header feststellen und herausfinden wollen, welches Attribut falsch ist.

Wo es versagt

  • 4KB-Grenze — dies ist die Gesamtgröße einschließlich Name + Wert + alle Attribute. Ein typisches JWT beträgt 400–800 Bytes. Ein dickes mit vielen Claims beträgt 1–2 KB. Sie haben nicht viel Platz.
  • SameSite=Strict töten OAuth — wenn Ihr IdP nach der Anmeldung zurück zu Ihrer App leitet, handelt es sich um eine cross-site-Anfrage. SameSite=Strict bedeutet, dass Ihr Sitzungs-Cookie nicht gesendet wird. Verwenden Sie Lax für alles, was über OAuth-Flows läuft.
  • Cookie-Ordnung und Pfadabgleich — Wenn mehrere Cookies überlappende Pfade haben, sendet der Browser sie in einer undefinierten Reihenfolge. Verlassen Sie sich nicht auf Priorität.
  • Deprecation von Drittanbieter-Cookies — Chrome entfernt Drittanbieter-Cookies. Cross-site-Cookie-Abhängigkeiten sind eine mittelfristige Gefahr.

Die Debatte über JWT in localStorage (die tatsächliche Angriffsoberfläche)

Dies kommt in jeder Authentifizierungsdiskussion vor, und die meisten Leute, die darüber reden, sprechen miteinander vorbei.

Die Sorge bezüglich der Speicherung von JWTs in localStorage: Wenn Ihre Site eine XSS-Vulnerabilität hat, kann ein Angreifer durch ein Skript direkt den Token lesen und exfiltrieren. Der Angreifer hat nun einen gültigen Auth-Token, den er von überall und auf jedem Gerät nutzen kann, bis er abläuft.

Der Vorteil von HttpOnly-Cookies: JavaScript kann das Cookie nicht lesen, daher kann XSS es nicht exfiltrieren. Die Sitzung ist weiterhin nutzbar bei Anfragen (der Angreifer kann Anfragen aus dem Browser des Opfers über XSS machen), aber sie kann den Token nicht übernehmen, um ihn an anderen Orten zu verwenden. Dies beschränkt den Auswirkungsbereich.

Die ehrliche Meinung: das grundlegende Problem ist XSS, nicht die Speicherort. Wenn Sie XSS haben, ist ein HttpOnly-Cookie sinnvoller — der Angreifer kann den Token nicht außerhalb des Systems nutzen. Aber die Behebung von XSS ist ein sinnvolleres Ziel, das mit einer strengen Content-Security-Policy, keiner unvertrauten Drittanbieter-Skript und richtiger Ausgabe-Entscheidung erreicht werden kann.

Wenn Sie eine SPA mit einer strengen CSP und ohne Drittanbieter-JS, die Sie nicht kontrollieren, bauen, ist localStorage für JWTs wahrscheinlich in Ordnung. Wenn Sie eine Site mit Google Tag Manager, Ad-Pixels und einer Dutzend npm-Abhängigkeiten betreiben, sind HttpOnly-Cookies viel sicherer, weil Ihr XSS-Angriffsbereich größer ist, als Sie denken.

Beim Debuggen von JWT-Problemen ist der JWT Decoder auf IO Tools nützlich — fügen Sie den Token ein und sehen Sie den Payload und die Ablaufzeit ohne Code zu schreiben. Der JWT Expiry Checker ist nützlich, um zu überprüfen, ob ein Token noch gültig ist, wenn Sie eine 401-Kaskade verfolgen.

Entscheidungsflussdiagramm

Bevor Sie ein Stack Overflow-Tab um 3 Uhr morgens öffnen, gehen Sie diesen Schritt durch:

  1. Bedarf der Serverseite, um es zu lesen? → Cookie. Ende der Diskussion.
  2. Ist es größer als 5 MB oder benötigt es Abfragefähigkeit? → IndexedDB.
  3. Sollte es beim Schließen des Tabs verschwinden? → sessionStorage.
  4. Alles andere → localStorage, mit angemessener Vorsicht darüber, was Sie speichern.

Das eine Dinge, das jeder falsch versteht

Speicher-APIs sind nicht zuverlässig für alle Benutzer zu jeder Zeit. Sie können durch den Browser, das Betriebssystem, Datenschutz-Einstellungen oder den Benutzer gelöscht werden. Jede Architektur, die den Clientseitenspeicher als Quelle der Wahrheit betrachtet — anstatt als Cache — wird bei jemandem schließlich scheitern.

Das Muster, das hält: behandeln Sie Browser-Speicher als Leistungsoptimierung gegenüber Ihrer echten Quelle der Wahrheit (dem Server). Cache aggressiv, aber entwerfen Sie Ihre App so, dass sie sich grundsätzlich erholen kann, wenn der Cache leer ist. Die 3-Uhr-Debug-Sitzungen sind fast nie über die verwendete Speicher-API — sie sind über die Annahme, dass die Daten da sein werden, wenn sie nicht da sind.

Möchten Sie werbefrei genießen? Werde noch heute werbefrei

Erweiterungen installieren

IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche

Zu Chrome-Erweiterung Zu Kantenerweiterung Zu Firefox-Erweiterung Zu Opera-Erweiterung

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!

ANZEIGE Entfernen?
ANZEIGE Entfernen?
ANZEIGE Entfernen?

Nachrichtenecke mit technischen Highlights

Beteiligen Sie sich

Helfen Sie uns, weiterhin wertvolle kostenlose Tools bereitzustellen

Kauf mir einen Kaffee
ANZEIGE Entfernen?