Safari:IndexedDB:无法在单独的事务中创建对象存储
Safari: IndexedDB: Cannot create object stores in separate transactions
Safari 和 iPhone 网络浏览器似乎无法允许用户从单独的事务创建不同的对象存储。甚至当用户关闭数据库、增加版本号然后在 onupgradedneeded 回调中使用 createObjectStore() 时也是如此。
有解决办法吗?
例如,在 Safari 中访问 http://bl.ocks.org/redgeoff/1dea140c52397d963377,当 Safari 尝试创建第二个对象存储时,您将收到带有 "AbortError" 的警报。
为方便起见,这里是相同的代码片段:
var idb = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB
|| window.msIndexedDB;
// Generate a unique db name as IndexedDB is very delicate and we want our test
// to focus on a new DB
var dbName = 'mydb' + '_' + (new Date()).getTime() + '_'
+ Math.round(1000000*Math.random());
var db = null;
var version = 1;
var open = function (version, onSuccess, onUpgradeNeeded) {
var request = null;
if (version) {
request = idb.open(dbName, version);
} else { // 1st time opening?
request = idb.open(dbName);
}
request.onupgradeneeded = function () {
if (onUpgradeNeeded) {
onUpgradeNeeded(request);
}
};
request.onsuccess = function () {
db = request.result;
if (onSuccess) {
onSuccess(request);
}
};
request.onerror = function () {
console.log('error=', request.error);
alert('error=' + JSON.stringify(request.error));
};
};
var createObjectStore = function (name, callback) {
db.close(); // synchronous
version++; // increment version to trigger onupgradeneeded
open(version, callback, function (request) {
request.result.createObjectStore(name, {
keyPath: 'id'
});
});
};
// NOTE: we could create the first store when opening the DB for the first time, but we'll keep
// things simple and reuse our createObjectStore code for both object stores
open(null, function () {
createObjectStore('store1', function () {
createObjectStore('store2', function () {
console.log('done creating both stores');
});
});
});
我尝试在数据库关闭并重新打开后休眠 2 秒,但这似乎不起作用。如果没有解决方法,那么这实际上意味着您不能在 Safari 中使用 IndexedDB 实现来动态创建对象存储,这意味着您需要在创建 DB 之前了解所有对象存储。
除非我弄错了并且有人有变通方法,否则动态添加对象存储的最佳方法是实现一个 db-per-object-store 设计。换句话说,您应该在需要创建新对象存储时创建一个新数据库。
另一个不错的选择是使用 https://github.com/axemclion/IndexedDBShim 通过 WebSQL 模拟 IndexedDB。
Safari 和 iPhone 网络浏览器似乎无法允许用户从单独的事务创建不同的对象存储。甚至当用户关闭数据库、增加版本号然后在 onupgradedneeded 回调中使用 createObjectStore() 时也是如此。
有解决办法吗?
例如,在 Safari 中访问 http://bl.ocks.org/redgeoff/1dea140c52397d963377,当 Safari 尝试创建第二个对象存储时,您将收到带有 "AbortError" 的警报。
为方便起见,这里是相同的代码片段:
var idb = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB
|| window.msIndexedDB;
// Generate a unique db name as IndexedDB is very delicate and we want our test
// to focus on a new DB
var dbName = 'mydb' + '_' + (new Date()).getTime() + '_'
+ Math.round(1000000*Math.random());
var db = null;
var version = 1;
var open = function (version, onSuccess, onUpgradeNeeded) {
var request = null;
if (version) {
request = idb.open(dbName, version);
} else { // 1st time opening?
request = idb.open(dbName);
}
request.onupgradeneeded = function () {
if (onUpgradeNeeded) {
onUpgradeNeeded(request);
}
};
request.onsuccess = function () {
db = request.result;
if (onSuccess) {
onSuccess(request);
}
};
request.onerror = function () {
console.log('error=', request.error);
alert('error=' + JSON.stringify(request.error));
};
};
var createObjectStore = function (name, callback) {
db.close(); // synchronous
version++; // increment version to trigger onupgradeneeded
open(version, callback, function (request) {
request.result.createObjectStore(name, {
keyPath: 'id'
});
});
};
// NOTE: we could create the first store when opening the DB for the first time, but we'll keep
// things simple and reuse our createObjectStore code for both object stores
open(null, function () {
createObjectStore('store1', function () {
createObjectStore('store2', function () {
console.log('done creating both stores');
});
});
});
我尝试在数据库关闭并重新打开后休眠 2 秒,但这似乎不起作用。如果没有解决方法,那么这实际上意味着您不能在 Safari 中使用 IndexedDB 实现来动态创建对象存储,这意味着您需要在创建 DB 之前了解所有对象存储。
除非我弄错了并且有人有变通方法,否则动态添加对象存储的最佳方法是实现一个 db-per-object-store 设计。换句话说,您应该在需要创建新对象存储时创建一个新数据库。
另一个不错的选择是使用 https://github.com/axemclion/IndexedDBShim 通过 WebSQL 模拟 IndexedDB。