indexedDB使用過程中常常會出現以下錯誤:
Failed to execute ‘createObjectStore’ on ‘IDBDatabase’: The database is not running a version change transaction.
這是由于你在success事件的回調中調用createObjectStore方法,該方法應該在upgradeneeded事件的回調中調用。
\\擷取indexedDB對象
const indexedDB = window.indexedDB || window.webkitIndexedDB ||
window.mozIndexedDB;
\\打開資料庫,在回調中建立store object
const request = indexedDB.open(DBName, version);
request.onsuccess = (e) => {
this.db = e.target.result;
};
request.onupgradeneeded = (e) => {
this.db = e.target.result;
if(!this.db.objectStoreNames.contains(storeName)){
this.store = this.db.createObjectStore(storeName, { keyPath: 'key'});
}
}
request.onerror = (e) => {console.log('Can not open indexedDB', e);};
這裡還可能出現另一個錯誤:
Failed to exectue ‘transaction’ on ‘IDBDatabase’: One of the specified stores was not found.
這是因為upgradeneeded事件沒有被觸發。
這裡需要注意upgradeneeded事件。首先,根據API,應該在upgradneeded事件的回調函數中調用createObjectStore方法建立store object,不應該在success的回調中,否則會報錯。其次,當為open方法傳入一個本域沒有的資料庫名時,會建立相應的資料庫,并觸發success、upgradeneeded事件,進而建立一個store object。但是,chrome54并不會觸發upgradeneeded事件,造成store object不會被建立,後續在store object上建立事務并操作資料時候就會報錯。Stackoverflow上提供的解決辦法是,在open方法傳入第二個參數(與已有version不同,且更大),這樣就會觸發chrome上的upgradeneeded事件了。不過,每次都需要調用db.version擷取目前的版本号。
另外可能出現的一個錯誤是:
Cannot read property ‘createObjectStore’ of undefined
這是因為indexedDB是異步的,你必須在回調函數中使用createObjectStore方法,即使你把createObjectStore調用寫在open函數後面,也無法保證哪個先完成。