Mobile Safari 10 IndexedDB Blob

Ben*_* E. 6 javascript safari mobile-safari indexeddb

Safari 10中的IndexedDB现在支持blob.这在桌面上工作正常,但iOS 10上的移动Safari会抛出错误:

UnknownError
Run Code Online (Sandbox Code Playgroud)

有时结合:

TransactionInactiveError (DOM IDBDatabase Exception): Failed to store record in an IDBObjectStore:
The transaction is inactive or finished.
Run Code Online (Sandbox Code Playgroud)

代码(缩写):

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在Mobile上,Safari 10 .put()不会像以前那样抛出,只是在异步错误回调中.

Base64字符串工作正常.

移动Safari中的错误还是我必须更改代码?

测试用例:http://fiddle.jshell.net/j7wh60vo/7/

Aug*_*ley 12

遇到同样的问题.Chrome 54和Safari 10在桌面上运行良好,但在Mobile Safari上,我Unknown在尝试将Blob存储到IndexedDB时不断收到错误.我可以确认这确实只是Mobile Safari上Blob的一个问题,而不是一些滥用API的问题.

幸运的是,ArrayBuffers工作正常.所以我改为下载图像:

xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
Run Code Online (Sandbox Code Playgroud)

然后将它们作为ArrayBuffers保存到IndexedDB中,并在将它们拉出以获取URL后将它们转换为Blob:

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);
  };
};
Run Code Online (Sandbox Code Playgroud)

我宁愿不必像这样将ArrayBuffers转换为Blob,因为我认为存在性能损失.但它的确有效.