Start · Sprachen · JavaScript · Referenz · Storage

Storage

Schnittstelle

Das <code>Storage</code>-Interface der Web Storage API bietet synchronen Schlüssel-Wert-Zugriff auf den lokalen oder den Sitzungsspeicher eines Ursprungs (Origin).

seit JavaScript Baseline: alle Browser (seit ca. 2009, HTML5) Kategorie: webapi

Signatur

interface Storage

Beschreibung

Das Interface Storage ist der gemeinsame Typ hinter window.localStorage und window.sessionStorage. Man erzeugt es nicht selbst: Der Browser stellt pro Ursprung (Protokoll + Host + Port) je eine Instanz bereit. Die Daten werden als einfache Schlüssel-Wert-Paare abgelegt, wobei Schlüssel und Werte immer Strings sind.

Die wichtigsten Mitglieder sind:

  • setItem(key, value): legt einen Eintrag an oder überschreibt ihn.
  • getItem(key): liest einen Wert, oder null, wenn der Schlüssel fehlt.
  • removeItem(key): entfernt einen Eintrag.
  • clear(): löscht alle Einträge dieses Speichers.
  • key(index): gibt den Schlüssel an Position index zurück, oder null.
  • length: Anzahl der gespeicherten Einträge (nur lesbar).

localStorage bleibt über Browser-Neustarts hinweg erhalten, bis Skript oder Nutzer die Daten löschen. sessionStorage gilt nur für den jeweiligen Tab bzw. das Fenster und verschwindet, wenn der Tab geschlossen wird. Beide eignen sich für kleine Datenmengen wie Nutzereinstellungen, Formularentwürfe oder UI-Zustände, typischerweise ungefähr 5 MiB pro Ursprung.

Alle Zugriffe laufen synchron und blockieren den Haupt-Thread. Für große oder strukturierte Datenmengen ist deshalb IndexedDB besser geeignet. Wenn sich localStorage in einem anderen Tab desselben Ursprungs ändert, erhalten die übrigen Tabs das Event storage.

Rückgabewert

Typ
Storage
Beschreibung
Man erhält eine Instanz über window.localStorage oder window.sessionStorage. Ein öffentlicher Konstruktor existiert nicht: new Storage() wirft einen TypeError.

Beispiele

Grundoperationen: setzen, lesen, entfernen

// Instanz vom Browser: localStorage ist vom Typ Storage
console.log(localStorage instanceof Storage);

localStorage.setItem('theme', 'dark');
console.log(localStorage.getItem('theme'));
console.log(localStorage.getItem('gibtEsNicht'));

localStorage.removeItem('theme');
console.log(localStorage.length);
true dark null 0

Objekte als JSON speichern (mit sicherem Einlesen)

const saveSettings = (settings) => {
  localStorage.setItem('settings', JSON.stringify(settings));
};

const loadSettings = (fallback = { fontSize: 16, lang: 'de' }) => {
  const raw = localStorage.getItem('settings');
  if (raw === null) return fallback;
  try {
    return { ...fallback, ...JSON.parse(raw) };
  } catch {
    return fallback; // beschädigte Daten ignorieren
  }
};

saveSettings({ fontSize: 18 });
console.log(loadSettings());
{ fontSize: 18, lang: 'de' }

Alle Einträge auflisten und Formularentwurf in sessionStorage halten

sessionStorage.setItem('draft:title', 'Mein Artikel');
sessionStorage.setItem('draft:body', 'Erster Absatz …');

for (let i = 0; i < sessionStorage.length; i++) {
  const key = sessionStorage.key(i);
  console.log(`${key} = ${sessionStorage.getItem(key)}`);
}

// Entwurf nach erfolgreichem Absenden verwerfen
const clearDraft = () => {
  Object.keys(sessionStorage)
    .filter((k) => k.startsWith('draft:'))
    .forEach((k) => sessionStorage.removeItem(k));
};
clearDraft();
console.log(sessionStorage.length);
draft:title = Mein Artikel draft:body = Erster Absatz … 0

Speicherlimit abfangen und Tabs synchronisieren

const safeSet = (key, value) => {
  try {
    localStorage.setItem(key, value);
    return true;
  } catch (err) {
    if (err.name === 'QuotaExceededError') {
      console.warn('Speicher voll – Eintrag nicht gespeichert.');
    }
    return false;
  }
};

safeSet('cart', JSON.stringify([{ id: 42, qty: 1 }]));

// Wird nur in ANDEREN Tabs desselben Ursprungs ausgelöst
window.addEventListener('storage', (event) => {
  if (event.storageArea === localStorage && event.key === 'cart') {
    console.log('Warenkorb geändert:', event.newValue);
  }
});

// Wichtig · Fallstricke

  • Nur Strings: Andere Werte werden in Strings umgewandelt. setItem('n', 1) ergibt beim Lesen "1", und ein Objekt wird zu "[object Object]". Deshalb Objekte mit JSON.stringify und JSON.parse umwandeln.
  • Kein sicherer Ort für Geheimnisse: Jedes Skript auf der Seite kann den Speicher lesen, auch per XSS eingeschleuster Code. Zugangstoken oder Sitzungs-IDs gehören besser in HttpOnly-Cookies. Gelesene Werte nie ungeprüft per innerHTML einfügen.
  • Ausnahmen: setItem wirft QuotaExceededError, wenn das Limit erreicht ist. In manchen Umgebungen wirft schon der Zugriff auf localStorage einen SecurityError, etwa bei blockierten Cookies oder in Sandbox-iframes. Zugriffe daher in try/catch kapseln.
  • Synchron: Große oder häufige Schreibvorgänge blockieren den Haupt-Thread. In Web- und Service-Workern ist Storage nicht verfügbar.
  • Eigenschaftszugriff vermeiden: localStorage.foo = 'x' funktioniert zwar, kann aber mit eingebauten Methodennamen wie key oder length kollidieren. Besser immer setItem/getItem verwenden.
  • Das Event storage wird nur in anderen Dokumenten ausgelöst, nicht im Tab, der die Änderung vorgenommen hat.
  • Privater Modus: Hier wird der Speicher beim Schließen gelöscht. Safari entfernt Skript-Speicher außerdem nach 7 Tagen ohne Nutzerinteraktion (ITP).