Signatur
Beschreibung
Das Ereignis blocked wird an einem IDBOpenDBRequest ausgelöst, wenn indexedDB.open() mit einer höheren Versionsnummer oder indexedDB.deleteDatabase() aufgerufen wird, während noch andere Verbindungen zur selben Datenbank offen sind, zum Beispiel in einem anderen Tab, einem Worker oder im eigenen Code. Vorher schickt der Browser jeder dieser Verbindungen ein versionchange-Ereignis. Schließt danach nicht jede Verbindung mit db.close(), wird blocked ausgelöst.
Der Handler lässt sich mit request.addEventListener("blocked", handler) oder über die Eigenschaft request.onblocked = handler registrieren. Das Ereignisobjekt ist ein IDBVersionChangeEvent mit oldVersion (aktuelle Version) und newVersion (gewünschte Version, bei deleteDatabase() ist sie null).
Wichtig: blocked ist kein Fehler, und die Anfrage wird nicht abgebrochen. Sie wartet weiter. Sobald alle anderen Verbindungen geschlossen sind, geht es mit upgradeneeded und success weiter (bzw. mit success beim Löschen). Typischerweise zeigt man im Handler einen Hinweis an, etwa „Bitte schließen Sie andere Tabs dieser Anwendung“.
Das Ereignis wird nicht weitergereicht (bubbling) und lässt sich nicht abbrechen. Am zuverlässigsten vermeidet man es, indem jede Verbindung auf versionchange mit db.close() reagiert.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Name des Ereignisses: "blocked". |
|
| $handler Pflicht | (event: IDBVersionChangeEvent) => void | Callback, der ein IDBVersionChangeEvent mit oldVersion und newVersion bekommt. |
|
| $options | boolean | AddEventListenerOptions | false | Optionale Einstellungen für addEventListener, z. B. { once: true }. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein IDBVersionChangeEvent.Beispiele
Upgrade blockiert – Hinweis anzeigen (addEventListener)
const request = indexedDB.open('notizen', 3);
request.addEventListener('blocked', (event) => {
console.warn(`Upgrade von v${event.oldVersion} auf v${event.newVersion} blockiert.`);
alert('Bitte schließen Sie andere Tabs dieser Anwendung, um fortzufahren.');
});
request.addEventListener('upgradeneeded', (event) => {
const db = request.result;
if (!db.objectStoreNames.contains('eintraege')) {
db.createObjectStore('eintraege', { keyPath: 'id', autoIncrement: true });
}
});
request.addEventListener('success', () => {
console.log('Datenbank bereit, Version', request.result.version);
});
Blockieren vermeiden: auf versionchange reagieren
const openDb = (name, version) => new Promise((resolve, reject) => {
const req = indexedDB.open(name, version);
req.onsuccess = () => {
const db = req.result;
// Andere Tabs wollen upgraden: eigene Verbindung freigeben
db.onversionchange = () => {
db.close();
console.log('Verbindung geschlossen – neue Version verfügbar, bitte neu laden.');
};
resolve(db);
};
req.onerror = () => reject(req.error);
req.onblocked = () => console.warn('Warte auf das Schließen anderer Verbindungen …');
});
const db = await openDb('notizen', 3);
console.log(db.name, db.version);
Datenbank löschen mit onblocked-Property
const deleteDb = (name) => new Promise((resolve, reject) => {
const req = indexedDB.deleteDatabase(name);
req.onblocked = (event) => {
// Bei deleteDatabase ist newVersion null
console.warn('Löschen blockiert, newVersion =', event.newVersion);
};
req.onsuccess = () => resolve('gelöscht');
req.onerror = () => reject(req.error);
});
console.log(await deleteDb('notizen'));
Eigene Verbindung als Ursache
const first = await new Promise((res) => {
const r = indexedDB.open('demo', 1);
r.onsuccess = () => res(r.result);
});
const upgrade = indexedDB.open('demo', 2);
upgrade.onblocked = () => {
console.log('Blockiert durch eigene Verbindung – schließe sie.');
first.close(); // danach läuft das Upgrade weiter
};
upgrade.onsuccess = () => console.log('Version jetzt', upgrade.result.version);
// Wichtig · Fallstricke
- Kein Abbruch: Nach
blockedbleibt die Anfrage offen. Kommt keindb.close(), bleibt sie ohne Zeitlimit hängen. Bei Bedarf eine eigene Zeitüberwachung einbauen und den Nutzer informieren. - Reihenfolge: Zuerst bekommen die offenen Verbindungen
versionchange. Schließen alle sofort, wirdblockedgar nicht ausgelöst. - Häufige Ursache: Die eigene Anwendung hält eine alte Verbindung (Singleton, Service Worker, zweiter Tab). Jede Verbindung sollte einen
onversionchange-Handler mitdb.close()haben. - Bei
deleteDatabase()istevent.newVersiongleichnull. - Ältere Safari-Versionen hatten Fehler beim Auslösen von
blocked. Ansonsten ist das Ereignis in allen modernen Browsern und in Workern verfügbar. - Im privaten Modus mancher Browser ist IndexedDB eingeschränkt oder flüchtig.