Zum Inhalt springen
aviral gupta

// I6.4 · ca. 36 Min. · Aufbau

localStorage, sessionStorage und IndexedDB

Nach dieser Lektion halten Sie Einstellungen und kleine Listen mit localStorage im Browser, speichern Objekte sicher als JSON und sagen, wann IndexedDB die bessere Wahl ist.

Lektion 4 von 5 in I6 Netzwerkanfragen und Speicher im Client

Danach können Sie

  • Werte mit setItem, getItem, removeItem und clear speichern, lesen und entfernen und für einen fehlenden Schlüssel null erwarten
  • Zahlen, Arrays und Objekte mit JSON als Strings speichern, mit einem Standardwert für einen fehlenden oder kaputten Wert
  • Zwischen localStorage, sessionStorage und IndexedDB nach Origin, Lebensdauer, Größe und Geschwindigkeit wählen
  1. Aufwärmen · Aufgabe 1 von 7

    Aufwärmen aus Lektion I6.1: der Body einer POST-Anfrage. Was gibt das aus?

    const body = JSON.stringify({title: "Dune", year: 1965});
    console.log(typeof body, body);
  2. Vorhersagen · Aufgabe 2 von 7

    Raten Sie, bevor Sie weiterlesen. Was gibt das aus?

    localStorage.setItem("count", 3);
    const count = localStorage.getItem("count");
    console.log(count + 1);
  3. Üben · Aufgabe 3 von 7

    Ergänzen Sie die Methode, die "dark" unter dem Schlüssel "theme" speichert.

    localStorage.____("theme", "dark");
    localStorage.("theme", "dark");
  4. Üben · Aufgabe 4 von 7

    Der Speicher dieser Origin ist noch leer. Was gibt das aus?

    console.log(localStorage.getItem("nothing"), localStorage.length);
  5. Üben · Aufgabe 5 von 7

    Ein Objekt geht direkt in localStorage. Was gibt das aus?

    localStorage.setItem("user", {name: "Ada"});
    console.log(localStorage.getItem("user"));
  6. Denksport · Aufgabe 6 von 7

    Knobelaufgabe. "cart" wurde nie gespeichert. Was gibt das aus?

    const cart = JSON.parse(localStorage.getItem("cart")) ?? [];
    cart.push("Dune");
    localStorage.setItem("cart", JSON.stringify(cart));
    console.log(localStorage.getItem("cart"), typeof localStorage.getItem("cart"));
  7. Anwenden · Aufgabe 7 von 7

    Mini-Aufgabe: Schreiben Sie loadSettings() und saveSettings(settings) für die Einstellungen {theme: "light", fontSize: 16}. loadSettings liefert die gespeicherten Einstellungen, mit den Standardwerten für alles Fehlende, und die Standardwerte, wenn nichts oder etwas Kaputtes gespeichert ist. Probieren Sie es in der Browser-Konsole einer Seite aus, die ein lokaler Webserver ausliefert: laden, das dunkle Theme speichern, wieder laden, dann den Wert von Hand kaputt machen.

    Prüfen Sie Ihr Ergebnis anhand dieser Liste

Selbst programmieren

Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.

Ausgearbeitetes Beispiel

Ein Besuchszähler und eine gespeicherte Liste

Die Seite zählt ihre Besuche und hält eine Leseliste in localStorage. main.js speichert eine Zahl und liest sie als String zurück, speichert ein Array als JSON und lädt es wieder und zeigt, was mit einem Wert passiert, der ohne JSON.stringify gespeichert wurde. Am Ende leert es den Speicher, damit jeder Lauf gleich beginnt.

main.js

// Numbers come back as strings.
const visits = Number(localStorage.getItem("visits") ?? 0) + 1;
localStorage.setItem("visits", visits);
console.log("visits:", localStorage.getItem("visits"), typeof localStorage.getItem("visits"));
console.log("missing key:", localStorage.getItem("nothing"));

// Arrays and objects go through JSON.
function loadBooks() {
  try {
    return JSON.parse(localStorage.getItem("books")) ?? [];
  } catch {
    return []; // broken data: start with an empty list
  }
}
function saveBooks(books) {
  localStorage.setItem("books", JSON.stringify(books));
}

saveBooks([...loadBooks(), "Dune", "Emma"]);
console.log("stored:", localStorage.getItem("books"));
const books = loadBooks();
console.log("loaded:", books, books.length);

localStorage.setItem("books", "Dune,Emma"); // saved without JSON.stringify
console.log("broken:", loadBooks());

document.querySelector("#visits").textContent = "Visit number " + visits;
const list = document.querySelector("#books");
for (const title of books) {
  const item = document.createElement("li");
  item.textContent = title;
  list.append(item);
}

localStorage.clear();
console.log("after clear:", localStorage.length);

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Reading list</title>
</head>
<body>
  <h1>My reading list</h1>
  <p id="visits"></p>
  <ul id="books"></ul>
  <script type="module" src="main.js"></script>
</body>
</html>

Um die Seite auf Ihrem Computer auszuführen, öffnen Sie index.html über einen lokalen Webserver, nicht als Datei: Browser führen Modul-Skripte von file://-Adressen nicht aus. Für die Prüfungen installieren Sie zuerst jsdom (die Befehle unten).

Ausgabe

visits: 1 string
missing key: null
stored: ["Dune","Emma"]
loaded: [ 'Dune', 'Emma' ] 2
broken: []
after clear: 0
<!-- #books -->
<ul id="books"><li>Dune</li><li>Emma</li></ul>
  • Der Besuchszähler wurde als Zahl 1 gespeichert und kam als String "1" zurück.
  • Die gespeicherte Liste ist der JSON-Text; JSON.parse hat daraus wieder ein Array gemacht.
  • "Dune,Emma" ist kein JSON, daher fiel loadBooks auf eine leere Liste zurück, statt abzustürzen.
Ändern und ausführen

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Ihre Seite

Ihre Seite läuft in einem abgeschotteten Rahmen. Sie hat keinen Zugriff auf diese Website, und ihr localStorage liegt nur für diesen Lauf im Speicher: Der nächste Lauf beginnt leer.

Führen Sie das Programm aus, um seine Seite hier zu sehen.

Übungen

Übung 1 von 3

Das Theme merken

Die Seite zeigt das Theme und hat die Buttons Light und Dark. Beim Laden zeigt sie schon das gespeicherte Theme oder light. Ein Klick zeigt das gewählte Theme, aber der Starter speichert es nie, daher ist die Seite nach einem Neuladen wieder hell. Speichern Sie die Auswahl unter dem Schlüssel "theme".

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Ihre Seite

Ihre Seite läuft in einem abgeschotteten Rahmen. Sie hat keinen Zugriff auf diese Website, und ihr localStorage liegt nur für diesen Lauf im Speicher: Der nächste Lauf beginnt leer.

Führen Sie das Programm aus, um seine Seite hier zu sehen.

Hinweise
  1. Hinweis 1

    Führen Sie die Tests aus: Nach einem Klick hat localStorage kein theme. Wo speichert die Seite überhaupt etwas?

  2. Hinweis 2

    Der Klick-Listener kennt das gewählte Theme.

  3. Hinweis 3

    localStorage.setItem("theme", theme); im Klick-Listener

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

const label = document.querySelector("#theme");

function show(theme) {
  document.body.className = theme;
  label.textContent = "Theme: " + theme;
}

show(localStorage.getItem("theme") ?? "light");

for (const theme of ["light", "dark"]) {
  document.querySelector("#" + theme).addEventListener("click", () => {
    show(theme);
    localStorage.setItem("theme", theme);
  });
}
Auf dem eigenen Computer ausführen

Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.js

const label = document.querySelector("#theme");

function show(theme) {
  document.body.className = theme;
  label.textContent = "Theme: " + theme;
}

show(localStorage.getItem("theme") ?? "light");

for (const theme of ["light", "dark"]) {
  document.querySelector("#" + theme).addEventListener("click", () => {
    show(theme);
  });
}

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {loadPage} from './learnrun.js';

const text = (page, selector) => page.document.querySelector(selector).textContent;
const click = (page, selector) => page.document.querySelector(selector).click();

test('Without a saved theme the page shows light', async () => {
  const page = await loadPage();
  assert.equal(text(page, '#theme'), 'Theme: light', `the page shows ${text(page, '#theme')}`);
});

test('A saved theme is shown on load', async () => {
  const page = await loadPage({localStorage: {theme: 'dark'}});
  assert.equal(text(page, '#theme'), 'Theme: dark', `the page shows ${text(page, '#theme')}`);
});

test('The chosen theme is still there after a reload', async () => {
  const page = await loadPage();
  click(page, '#dark');
  assert.equal(page.window.localStorage.getItem('theme'), 'dark', `localStorage has theme ${page.window.localStorage.getItem('theme')}`);
  const reloaded = await loadPage({localStorage: page.window.localStorage});
  assert.equal(text(reloaded, '#theme'), 'Theme: dark', `after a reload the page shows ${text(reloaded, '#theme')}`);
});

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Theme</title>
</head>
<body>
  <p id="theme"></p>
  <button id="light" type="button">Light</button>
  <button id="dark" type="button">Dark</button>
  <script type="module" src="main.js"></script>
</body>
</html>

package.json

{
  "type": "module"
}

package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.

Programm ausführen:

Um die Seite auf Ihrem Computer auszuführen, öffnen Sie index.html über einen lokalen Webserver, nicht als Datei: Browser führen Modul-Skripte von file://-Adressen nicht aus. Für die Prüfungen installieren Sie zuerst jsdom (die Befehle unten).

Prüfungen ausführen (learnrun.js muss im selben Ordner liegen):

npm install jsdom@28.1.0
node --test
learnrun.js herunterladen

Übung 2 von 3

Eine Leseliste, die ein Neuladen übersteht

Die Seite hält eine Leseliste unter dem Schlüssel "books". Sie lädt die Liste schon sicher und fügt bei jedem Klick auf Add einen Titel hinzu. Aber der Starter speichert das Array selbst, das localStorage zu "Dune,Emma" macht, daher lässt sich die Liste nach einem Neuladen nicht parsen und ist leer. Speichern Sie sie als JSON.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Ihre Seite

Ihre Seite läuft in einem abgeschotteten Rahmen. Sie hat keinen Zugriff auf diese Website, und ihr localStorage liegt nur für diesen Lauf im Speicher: Der nächste Lauf beginnt leer.

Führen Sie das Programm aus, um seine Seite hier zu sehen.

Hinweise
  1. Hinweis 1

    Führen Sie die Tests aus: localStorage hat books = Dune,Emma. Was macht setItem mit einem Array?

  2. Hinweis 2

    Alles, was kein String ist, wird auf die Standardweise in einen umgewandelt. JSON behält die Klammern und Anführungszeichen.

  3. Hinweis 3

    localStorage.setItem("books", JSON.stringify(books));

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

const list = document.querySelector("#books");
const input = document.querySelector("#title");

function load() {
  try {
    return JSON.parse(localStorage.getItem("books")) ?? [];
  } catch {
    return []; // a broken value: start again
  }
}

function render(books) {
  list.replaceChildren(...books.map((title) => {
    const item = document.createElement("li");
    item.textContent = title;
    return item;
  }));
}

const books = load();
render(books);

document.querySelector("#add").addEventListener("click", () => {
  books.push(input.value);
  localStorage.setItem("books", JSON.stringify(books));
  render(books);
  input.value = "";
});
Auf dem eigenen Computer ausführen

Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.js

const list = document.querySelector("#books");
const input = document.querySelector("#title");

function load() {
  try {
    return JSON.parse(localStorage.getItem("books")) ?? [];
  } catch {
    return []; // a broken value: start again
  }
}

function render(books) {
  list.replaceChildren(...books.map((title) => {
    const item = document.createElement("li");
    item.textContent = title;
    return item;
  }));
}

const books = load();
render(books);

document.querySelector("#add").addEventListener("click", () => {
  books.push(input.value);
  localStorage.setItem("books", books);
  render(books);
  input.value = "";
});

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {loadPage} from './learnrun.js';

const text = (page, selector) => page.document.querySelector(selector).textContent;
const click = (page, selector) => page.document.querySelector(selector).click();

const titles = (page) => [...page.document.querySelectorAll('#books li')].map((item) => item.textContent);
function add(page, title) {
  page.document.querySelector('#title').value = title;
  click(page, '#add');
}

test('Saved books are shown on load', async () => {
  const page = await loadPage({localStorage: {books: '["Dune","Emma"]'}});
  assert.deepEqual(titles(page), ['Dune', 'Emma'], `the list shows ${JSON.stringify(titles(page))}`);
});

test('A broken saved value gives an empty list', async () => {
  const page = await loadPage({localStorage: {books: '{oops'}});
  assert.deepEqual(titles(page), [], `the list shows ${JSON.stringify(titles(page))}`);
});

test('Added books are saved as JSON and survive a reload', async () => {
  const page = await loadPage();
  add(page, 'Dune');
  add(page, 'Emma');
  const saved = page.window.localStorage.getItem('books');
  assert.equal(saved, '["Dune","Emma"]', `localStorage has books = ${saved}`);
  const reloaded = await loadPage({localStorage: page.window.localStorage});
  assert.deepEqual(titles(reloaded), ['Dune', 'Emma'], `after a reload the list shows ${JSON.stringify(titles(reloaded))}`);
});

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Reading list</title>
</head>
<body>
  <input id="title" aria-label="Title">
  <button id="add" type="button">Add</button>
  <ul id="books"></ul>
  <script type="module" src="main.js"></script>
</body>
</html>

package.json

{
  "type": "module"
}

package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.

Programm ausführen:

Um die Seite auf Ihrem Computer auszuführen, öffnen Sie index.html über einen lokalen Webserver, nicht als Datei: Browser führen Modul-Skripte von file://-Adressen nicht aus. Für die Prüfungen installieren Sie zuerst jsdom (die Befehle unten).

Prüfungen ausführen (learnrun.js muss im selben Ordner liegen):

npm install jsdom@28.1.0
node --test
learnrun.js herunterladen

Übung 3 von 3

Ein Zähler, der weiterzählt

Die Seite zeigt einen Zähler und einen +1-Button und speichert den Zähler unter dem Schlüssel "count". Auf einer neuen Seite zählt sie 0, 1, 2. Aber bei einem gespeicherten Zähler von 4 zeigt ein Klick 41 statt 5: Der Starter addiert 1 zu dem String, den er gelesen hat. Machen Sie beim Laden der Seite aus dem gespeicherten Wert eine Zahl.

Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.

Beim ersten Ausführen lädt Ihr Browser den JavaScript-Runner herunter (bis zu 0.1 MB) und speichert ihn im Cache. Ihr Code läuft in der eigenen Engine Ihres Browsers und bleibt auf Ihrem Gerät.

Ihre Seite

Ihre Seite läuft in einem abgeschotteten Rahmen. Sie hat keinen Zugriff auf diese Website, und ihr localStorage liegt nur für diesen Lauf im Speicher: Der nächste Lauf beginnt leer.

Führen Sie das Programm aus, um seine Seite hier zu sehen.

Hinweise
  1. Hinweis 1

    Führen Sie die Tests aus: Ein gespeicherter Wert 4 wird zu 41. Welchen Typ liefert getItem zurück?

  2. Hinweis 2

    "4" + 1 hängt zwei Strings aneinander. Machen Sie den Wert einmal zu einer Zahl, wenn die Seite lädt.

  3. Hinweis 3

    let count = Number(localStorage.getItem("count") ?? 0);

Eine Lösung zeigen

Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.

const output = document.querySelector("#count");
let count = Number(localStorage.getItem("count") ?? 0);
output.textContent = count;

document.querySelector("#more").addEventListener("click", () => {
  count = count + 1;
  localStorage.setItem("count", count);
  output.textContent = count;
});
Auf dem eigenen Computer ausführen

Installieren Sie ECMAScript 2026 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.

main.js

const output = document.querySelector("#count");
let count = localStorage.getItem("count") ?? 0;
output.textContent = count;

document.querySelector("#more").addEventListener("click", () => {
  count = count + 1;
  localStorage.setItem("count", count);
  output.textContent = count;
});

main.test.js

import {test} from 'node:test';
import assert from 'node:assert/strict';
import {loadPage} from './learnrun.js';

const text = (page, selector) => page.document.querySelector(selector).textContent;
const click = (page, selector) => page.document.querySelector(selector).click();

test('A new page starts at 0 and counts to 1', async () => {
  const page = await loadPage();
  assert.equal(text(page, '#count'), '0', `at the start the page shows ${text(page, '#count')}`);
  click(page, '#more');
  assert.equal(text(page, '#count'), '1', `after one click the page shows ${text(page, '#count')}`);
});

test('A saved count of 4 goes on with 5', async () => {
  const page = await loadPage({localStorage: {count: '4'}});
  click(page, '#more');
  assert.equal(text(page, '#count'), '5', `after one click the page shows ${text(page, '#count')}`);
});

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Counter</title>
</head>
<body>
  <p id="count"></p>
  <button id="more" type="button">+1</button>
  <script type="module" src="main.js"></script>
</body>
</html>

package.json

{
  "type": "module"
}

package.json sagt Node.js, dass die .js-Dateien Module sind; lassen Sie die Datei im Ordner.

Programm ausführen:

Um die Seite auf Ihrem Computer auszuführen, öffnen Sie index.html über einen lokalen Webserver, nicht als Datei: Browser führen Modul-Skripte von file://-Adressen nicht aus. Für die Prüfungen installieren Sie zuerst jsdom (die Befehle unten).

Prüfungen ausführen (learnrun.js muss im selben Ordner liegen):

npm install jsdom@28.1.0
node --test
learnrun.js herunterladen

Häufige Fehler

Einen Schlüssel parsen, der nie gespeichert wurde

const books = JSON.parse(localStorage.getItem("books"));
document.querySelector("#out").textContent = books.length + " books";

Was Node.js ausgibt

TypeError: Cannot read properties of null (reading 'length')

Warum, und die Lösung

Beim ersten Besuch ist noch nichts gespeichert. getItem liefert null, und JSON.parse(null) ist ebenfalls null, ohne Fehler, der Absturz kommt also erst eine Zeile später. Geben Sie einen Standardwert an: const books = JSON.parse(localStorage.getItem("books")) ?? [];.

Ein Objekt ohne JSON.stringify speichern

localStorage.setItem("user", {name: "Ada"});
const user = JSON.parse(localStorage.getItem("user"));
document.querySelector("#out").textContent = user.name;

Was Node.js ausgibt

SyntaxError: "[object Object]" is not valid JSON

Warum, und die Lösung

setItem speichert nur Strings, das Objekt wurde also zum Text "[object Object]", der kein JSON ist. Speichern Sie es mit localStorage.setItem("user", JSON.stringify(user)) und behalten Sie JSON.parse zum Laden.

localStorage in einem Node.js-Programm

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

Was Node.js ausgibt

ReferenceError: localStorage is not defined

Warum, und die Lösung

localStorage gehört zum Browser. In Node.js 24 gibt es es nur, wenn node mit --experimental-webstorage gestartet wird, node main.js kennt es also nicht. Führen Sie Speichercode in einer Seite aus (index.html mit main.js, von einem lokalen Webserver); in Node.js halten Sie Daten stattdessen mit node:fs in einer Datei.

JavaScript im Browser: die eigene Engine Ihres Browsers in einem abgeschotteten Worker. Syntaxfehler findet acorn 8.18.0, MIT. Lizenz und Quellcode

Abschlussquiz

5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.

Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.

Problem melden

Etwas ist falsch oder unklar? Beschreiben Sie es kurz, dann wird es geprüft und korrigiert.

#

Mindestens 20 Zeichen.

Nur, wenn Sie eine Antwort wünschen.

Kernideen

Strings unter Schlüsseln, pro Origin

localStorage.setItem("theme", "dark") speichert einen Wert unter einem Schlüssel; getItem("theme") liest ihn, removeItem("theme") löscht ihn und clear() löscht alles. Schlüssel und Werte sind Strings: setItem("count", 3) speichert "3". getItem liefert null für einen Schlüssel, den es nicht gibt. Jede Origin (Schema, Host und Port) hat ihren eigenen Speicher, den andere Websites nicht lesen können, und er bleibt nach dem Schließen des Browsers bestehen. sessionStorage hat dieselben Methoden, gehört aber zu einem Tab und ist weg, wenn der Tab geschlossen wird.

Objekte über JSON, mit einem Standardwert

setItem("user", {name: "Ada"}) speichert den Text "[object Object]", und ein Array wird zu "Dune,Emma". Speichern Sie mit JSON.stringify und laden Sie mit JSON.parse. Ein fehlender Schlüssel liefert null, und JSON.parse(null) ist null, ergänzen Sie also einen Standardwert: JSON.parse(localStorage.getItem("books")) ?? []. Ein Wert kann auch kaputt sein, von einer älteren Version Ihres Codes gespeichert oder von Hand geändert, packen Sie JSON.parse also in try...catch. Zahlen kommen als Strings zurück: Number(localStorage.getItem("count") ?? 0).

Grenzen, andere Tabs und IndexedDB

Der Speicher pro Origin ist begrenzt: Ist er voll, wirft setItem einen QuotaExceededError. Web Storage ist synchron, jeder Aufruf blockiert also die Seite: Halten Sie es für Kleinigkeiten wie Einstellungen. Ändert ein anderer Tab derselben Origin localStorage, feuert das storage-Ereignis in Ihrem Tab, nicht in dem Tab, der die Änderung gemacht hat. Für viele Datensätze, Dateien oder die Suche nach einem Feld nutzen Sie IndexedDB: eine asynchrone Datenbank im Browser mit Object Stores, Indizes und Transaktionen. Sie ist aufwendiger in der Nutzung, wählen Sie sie also nur, wenn Sie sie brauchen.

Quellen

Zuletzt geprüft am 5. Oktober 2026