indexedDB使用過程中常常會出現以下錯誤:
Failed to execute ‘createObjectStore’ on ‘IDBDatabase’: The database is not running a version change transaction.
IDBDatabase.createObjectStore()
:創建存放數據的對象倉庫,類似於傳統關系型數據庫的表格,返回一個 IDBObjectStore 對象。該方法只能在versionchange
事件監聽函數中調用。
這是由於你在success事件的回調中調用createObjectStore方法,該方法應該在upgradeneeded事件的回調中調用。
//indexedDB.open()方法用於打開數據庫 var request = window.indexedDB.open("ppData", 1); var db; request.onupgradeneeded = function (event) { db = event.target.request; var objectStore; if (!db.objectStoreNames.contains('person')) { //objectStore = db.createObjectStore('person', { keyPath: 'id' }); objectStore = db.createObjectStore('uploadImg', { autoIncrement: true }); //objectStore.createIndex('name', 'name', { unique: false }); //objectStore.createIndex('email', 'email', { unique: true }); } } request.onsuccess = function (event) { db = request.result; console.log("數據庫打開成功"); } request.onerror = function(event){ console.log("數據庫打開報錯!"); }
這里還可能出現另一個錯誤:
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函數后面,也無法保證哪個先完成。