Start · Sprachen · JavaScript · Referenz · IDBOpenDBRequest

IDBOpenDBRequest

Schnittstelle

Anfrage-Objekt, das <code>indexedDB.open()</code> und <code>indexedDB.deleteDatabase()</code> zurückgeben, mit den zusätzlichen Events <code>upgradeneeded</code> und <code>blocked</code>.

seit JavaScript Baseline: alle Browser (seit 2015) Kategorie: webapi

Signatur

interface IDBOpenDBRequest extends IDBRequest

Beschreibung

IDBOpenDBRequest ist eine Unterklasse von IDBRequest. Ein solches Objekt bekommst du zurück, wenn du mit indexedDB.open(name, version) eine Datenbank öffnest oder sie mit indexedDB.deleteDatabase(name) löschst. Die Anfrage läuft asynchron. Das Ergebnis erhältst du über Events: Bei success steht in request.result die geöffnete IDBDatabase, bei error steht in request.error eine DOMException.

Gegenüber IDBRequest kommen zwei Events hinzu:

  • upgradeneeded (onupgradeneeded): Wird ausgelöst, wenn die Datenbank neu angelegt wird oder die angeforderte Version höher ist als die vorhandene. Nur in diesem Handler darfst du das Schema ändern, also Object Stores und Indizes mit createObjectStore() und createIndex() anlegen oder löschen. Das Event ist ein IDBVersionChangeEvent mit den Eigenschaften oldVersion und newVersion.
  • blocked (onblocked): Wird ausgelöst, wenn andere Verbindungen (z. B. in einem anderen Tab) die Datenbank noch geöffnet halten und deshalb das Upgrade oder das Löschen nicht weiterlaufen kann.

Für alle Events kannst du addEventListener() oder die entsprechenden on…-Properties verwenden. Die Reihenfolge ist fest: Zuerst kommt gegebenenfalls upgradeneeded, danach wird die Versionswechsel-Transaktion abgeschlossen und erst dann folgt success. Scheitert das Upgrade, folgt stattdessen error. In der Praxis verpackt man die Anfrage meist in ein Promise, damit man mit async/await arbeiten kann.

Parameter

Name Typ Default Beschreibung
$onupgradeneeded ((event: IDBVersionChangeEvent) => void) | null null Handler für die Schema-Migration. event.target.result ist die IDBDatabase, event.target.transaction ist die Versionswechsel-Transaktion.
$onblocked ((event: IDBVersionChangeEvent) => void) | null null Wird aufgerufen, wenn offene Verbindungen ein Upgrade oder das Löschen blockieren.
$onsuccess ((event: Event) => void) | null null Von IDBRequest geerbt: Die Datenbank wurde erfolgreich geöffnet bzw. gelöscht.
$onerror ((event: Event) => void) | null null Von IDBRequest geerbt: Beim Öffnen ist ein Fehler aufgetreten, z. B. VersionError oder AbortError.

Beispiele

Datenbank öffnen und Schema mit onupgradeneeded anlegen

const request = indexedDB.open('shop', 1);

request.onupgradeneeded = (event) => {
  const db = event.target.result;
  // Läuft nur beim ersten Anlegen oder bei einer höheren Version
  const store = db.createObjectStore('produkte', { keyPath: 'id' });
  store.createIndex('nachName', 'name', { unique: false });
  console.log(`Upgrade von ${event.oldVersion} auf ${event.newVersion}`);
};

request.onsuccess = () => {
  const db = request.result;
  console.log('Geöffnet:', db.name, 'Version', db.version);
};

request.onerror = () => console.error('Fehler:', request.error);
Upgrade von 0 auf 1 Geöffnet: shop Version 1

Promise-Wrapper mit addEventListener und inkrementeller Migration

const openDB = (name, version, migrate) =>
  new Promise((resolve, reject) => {
    const req = indexedDB.open(name, version);
    req.addEventListener('upgradeneeded', (e) => migrate(req.result, e.oldVersion, req.transaction));
    req.addEventListener('success', () => resolve(req.result));
    req.addEventListener('error', () => reject(req.error));
    req.addEventListener('blocked', () => console.warn('Bitte andere Tabs schließen.'));
  });

const db = await openDB('notizen', 2, (db, oldVersion, tx) => {
  if (oldVersion < 1) db.createObjectStore('notizen', { autoIncrement: true });
  if (oldVersion < 2) tx.objectStore('notizen').createIndex('datum', 'datum');
});

// Bei Upgrade durch einen anderen Tab: Verbindung freigeben
db.onversionchange = () => db.close();
console.log([...db.objectStoreNames]);
['notizen']

Datenbank löschen und blocked behandeln

const deleteDB = (name) =>
  new Promise((resolve, reject) => {
    const req = indexedDB.deleteDatabase(name);
    req.onsuccess = () => resolve(req.result); // undefined
    req.onerror = () => reject(req.error);
    req.onblocked = () => console.warn(`"${name}" ist noch in einem anderen Tab geöffnet.`);
  });

await deleteDB('shop');
console.log('Datenbank gelöscht');
Datenbank gelöscht

// Wichtig · Fallstricke

  • Schema-Änderungen nur in upgradeneeded: Rufst du createObjectStore() außerhalb dieses Handlers auf, wird ein InvalidStateError geworfen. Um das Schema zu ändern, musst du die Versionsnummer erhöhen.
  • Version: Die Version muss eine positive ganze Zahl sein. Fordert der Code eine niedrigere Version an als die vorhandene, führt das zu error mit einem VersionError. Lässt du die Version weg, wird die aktuelle Version geöffnet, bzw. bei einer neuen Datenbank Version 1.
  • Blockierte Upgrades: Solange eine andere Verbindung offen ist, bleibt die Anfrage nach blocked hängen. Registriere deshalb in jeder Verbindung db.onversionchange = () => db.close().
  • Kein await in upgradeneeded: Die Versionswechsel-Transaktion schließt sich automatisch, sobald keine Anfragen mehr offen sind. Wartest du dazwischen auf fremde Promises wie fetch, führt das zu TransactionInactiveError.
  • Kompatibilität: Wird von allen modernen Browsern und in Web Workern unterstützt. Im privaten Modus älterer Firefox- und Safari-Versionen war IndexedDB teilweise nicht verfügbar oder open() schlug fehl. Plane deshalb immer einen onerror-Zweig ein. IndexedDB unterliegt der Same-Origin-Policy und Speicherquoten.