Mobile Safari 10 IndexedDB Blob
Mobile Safari 10 IndexedDB Blobs
Safari 10 中的 IndexedDB 现在支持 blob。这在桌面上运行良好,但是 iOS 10 上的移动 Safari 会引发错误:
UnknownError
有时组合使用:
TransactionInactiveError (DOM IDBDatabase Exception): Failed to store record in an IDBObjectStore:
The transaction is inactive or finished.
代码(缩写):
var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB,
READ_WRITE = IDBTransaction && IDBTransaction.READ_WRITE ? IDBTransaction.READ_WRITE : 'readwrite',
storeName = 'files',
db;
init: function() {
var request = indexedDB.open('mydb');
request.onerror = ...;
request.onupgradeneeded = function() {
db = request.result;
db.createObjectStore(storeName);
};
request.onsuccess = function() {
db = request.result;
};
},
save: function(id, data) {
var put = function(data) {
var objectStore = db.transaction([storeName], READ_WRITE).objectStore(storeName),
request = objectStore.put(data, id);
request.onerror = ...;
request.onsuccess = ...;
};
// not all IndexedDB implementations support storing blobs, only detection is try-catch
try {
put(data);
} catch(err) {
if (data instanceof Blob) {
Helpers.blobToDataURL(data, put);
}
}
}
在 Mobile Safari 10 上 .put()
不会像以前那样抛出,只会在稍后的异步错误回调中抛出。
Base64 字符串工作正常。
Mobile Safari 中存在错误,还是我必须更改代码?
在我看来,这个错误就像您必须更改代码一样。该错误并不表示 blob 存在问题。该错误表明您在调用函数的某个地方有问题。为了更好地回答您的问题,您需要 post 更多的周边代码。具体来说,显示您创建交易和创建交易请求的代码部分。
编辑:首先,删除 window.indexedDB 内容。其次,不要按照你使用它的方式使用 'db',因为那将不起作用,数据库可能会在调用保存时关闭。
function save(id, data) {
var openRequest = indexedDB.open(...);
openRequest.onerror = console;
openRequest.onsuccess = function(event) {
var db = openRequest.result;
// Open the transaction
var tx = db.transaction(storeName, 'readwrite');
var store = tx.objectStore(storeName);
// Immediately use the transaction
try {
var putRequest = tx.put(data, id);
putRequest.onerror = console;
} catch(error) {
console.log(error);
}
};
}
Edit2:附加说明:
前缀已被删除,只使用 indexedDB,而不是 mozIndexedDB 或 webkitIndexedDB 等
事务模式常量已被删除,使用 'readonly' 或 'readwrite',或什么都不用(默认为只读)
我有点不明白你怎么称呼request = transaction.put
。据我所知,规范 https://w3c.github.io/IndexedDB/#idbtransaction 中没有方法 IDBTransaction.prototype.put。我很困惑为什么 Mozilla 文档显示带有 transaction.put 的示例。检查 IDBTransaction 的原型 Chrome 55 没有显示 put 方法。
有IDBObjectStore.prototype.put。您的代码根本不应该像当前编写的那样在任何平台上运行。因此,如果它确实有效,我会感到惊讶。你应该只使用像 var store = transaction.objectStore('store'); store.put(obj);
这样你调用对象存储的东西。
运行 跨过同样的问题。 Chrome 54 和 Safari 10 在桌面上运行良好,但在移动 Safari 上,我在尝试将 Blob 存储到 IndexedDB 时不断收到 Unknown
错误。我可以确认这确实只是 Mobile Safari 上 Blob 的问题,而不是 API.
的一些误用
幸运的是,ArrayBuffers 工作正常。所以我下载了如下图片:
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
然后以ArrayBuffers的形式保存到IndexedDB中,拉出来后转成Blob得到一个url:
putRequest = objectStore.put(arrayBuffer, id);
putRequest.onsuccess = function(event) {
objectStore.get(id).onsuccess = function(event) {
var blob = new Blob([event.target.result], { type: 'image/jpeg'});
var URL = window.URL || window.webkitURL;
blobUrl = URL.createObjectURL(blob);
};
};
我宁愿不必像这样将 ArrayBuffers 转换为 Blob,因为我认为这会降低性能。但它有效。
Safari 10 中的 IndexedDB 现在支持 blob。这在桌面上运行良好,但是 iOS 10 上的移动 Safari 会引发错误:
UnknownError
有时组合使用:
TransactionInactiveError (DOM IDBDatabase Exception): Failed to store record in an IDBObjectStore:
The transaction is inactive or finished.
代码(缩写):
var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB,
READ_WRITE = IDBTransaction && IDBTransaction.READ_WRITE ? IDBTransaction.READ_WRITE : 'readwrite',
storeName = 'files',
db;
init: function() {
var request = indexedDB.open('mydb');
request.onerror = ...;
request.onupgradeneeded = function() {
db = request.result;
db.createObjectStore(storeName);
};
request.onsuccess = function() {
db = request.result;
};
},
save: function(id, data) {
var put = function(data) {
var objectStore = db.transaction([storeName], READ_WRITE).objectStore(storeName),
request = objectStore.put(data, id);
request.onerror = ...;
request.onsuccess = ...;
};
// not all IndexedDB implementations support storing blobs, only detection is try-catch
try {
put(data);
} catch(err) {
if (data instanceof Blob) {
Helpers.blobToDataURL(data, put);
}
}
}
在 Mobile Safari 10 上 .put()
不会像以前那样抛出,只会在稍后的异步错误回调中抛出。
Base64 字符串工作正常。
Mobile Safari 中存在错误,还是我必须更改代码?
在我看来,这个错误就像您必须更改代码一样。该错误并不表示 blob 存在问题。该错误表明您在调用函数的某个地方有问题。为了更好地回答您的问题,您需要 post 更多的周边代码。具体来说,显示您创建交易和创建交易请求的代码部分。
编辑:首先,删除 window.indexedDB 内容。其次,不要按照你使用它的方式使用 'db',因为那将不起作用,数据库可能会在调用保存时关闭。
function save(id, data) {
var openRequest = indexedDB.open(...);
openRequest.onerror = console;
openRequest.onsuccess = function(event) {
var db = openRequest.result;
// Open the transaction
var tx = db.transaction(storeName, 'readwrite');
var store = tx.objectStore(storeName);
// Immediately use the transaction
try {
var putRequest = tx.put(data, id);
putRequest.onerror = console;
} catch(error) {
console.log(error);
}
};
}
Edit2:附加说明:
前缀已被删除,只使用 indexedDB,而不是 mozIndexedDB 或 webkitIndexedDB 等
事务模式常量已被删除,使用 'readonly' 或 'readwrite',或什么都不用(默认为只读)
我有点不明白你怎么称呼request = transaction.put
。据我所知,规范 https://w3c.github.io/IndexedDB/#idbtransaction 中没有方法 IDBTransaction.prototype.put。我很困惑为什么 Mozilla 文档显示带有 transaction.put 的示例。检查 IDBTransaction 的原型 Chrome 55 没有显示 put 方法。
有IDBObjectStore.prototype.put。您的代码根本不应该像当前编写的那样在任何平台上运行。因此,如果它确实有效,我会感到惊讶。你应该只使用像 var store = transaction.objectStore('store'); store.put(obj);
这样你调用对象存储的东西。
运行 跨过同样的问题。 Chrome 54 和 Safari 10 在桌面上运行良好,但在移动 Safari 上,我在尝试将 Blob 存储到 IndexedDB 时不断收到 Unknown
错误。我可以确认这确实只是 Mobile Safari 上 Blob 的问题,而不是 API.
幸运的是,ArrayBuffers 工作正常。所以我下载了如下图片:
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
然后以ArrayBuffers的形式保存到IndexedDB中,拉出来后转成Blob得到一个url:
putRequest = objectStore.put(arrayBuffer, id);
putRequest.onsuccess = function(event) {
objectStore.get(id).onsuccess = function(event) {
var blob = new Blob([event.target.result], { type: 'image/jpeg'});
var URL = window.URL || window.webkitURL;
blobUrl = URL.createObjectURL(blob);
};
};
我宁愿不必像这样将 ArrayBuffers 转换为 Blob,因为我认为这会降低性能。但它有效。