无法将Blob保存到indexedDB

7
我在IndexedDB中保存blob时遇到了麻烦,只有在使用blob时才会出现此问题。
如果我保存其他东西(如base64图像),一切都正常。
但是使用blob时,只会保存一个空对象属性。

控制台截图:

enter image description here

代码:

//prepared blob...
var openRequest = indexedDB.open("testDB",1);

openRequest.onupgradeneeded = function(e) {
    var thisDB = e.target.result;

    if(!thisDB.objectStoreNames.contains("stash")) {
        thisDB.createObjectStore("stash");
    }
}

openRequest.onsuccess = function(e) {
    db = e.target.result;

    var transaction = db.transaction(["stash"],"readwrite");
    var store = transaction.objectStore("stash");
    var tID = Date.now();

    var obj = {
        bl:blob,
        created:tID
    }
    console.log(obj);
    //add it 
    var request = store.add(obj, tID);
    request.onerror = function(e) {
        console.log("Error",e.target.error.name);
    }
    request.onsuccess = function(e) {
        console.log("success");
    }
}
openRequest.onerror = function(e) {
    //....
}

我还尝试过只保存blob(而非作为obj属性包装),但结果相同。
我可以将blob保存到HDD中,如果我在控制台上记录我的obj,我会得到:enter image description here
因此,我猜测blob是有效的,问题在于将其添加到indexedDB中。我对blob/indexedDB很陌生,可能犯了一些新手错误。请问有人能提供建议,我错在哪里了吗?
PS:没有任何错误消息

1
在Chrome中,IndexedDB存在许多Blob错误。 - wOxxOm
@wOxxOm 好的,谢谢你指出来。 - Wolf War
Chrome 开发者控制台在检查存储/索引时可能不会显示 Blob。您是否尝试编写代码将值读回并以编程方式进行检查? - Joshua Bell
@JoshuaBell 不,当我试图从代码中调用并对其进行操作时,它也是空的...如果这就是你的问题...在此期间对Chromium进行了一些更改,也许他们也修复了这个问题...我无法再测试它了。 - Wolf War
2个回答

7

这是一个非常老的问题,但现在已经支持将Blob存储在IndexedDb中:

// Create an example Blob object
var blob = new Blob(['blob object'], {type: 'text/plain'});

try {
    var store = db.transaction(['entries'], 'readwrite').objectStore('entries');

    // Store the object  
    var req = store.put(blob, 'blob');
    req.onerror = function(e) {
        console.log(e);
    };
    req.onsuccess = function(event) {
        console.log('Successfully stored a blob as Blob.');
    };
} catch (e) {
    var reader = new FileReader();
    reader.onload = function(event) {
        // After exception, you have to start over from getting transaction.
        var store = db.transaction(['entries'], 'readwrite').objectStore('entries');

        // Obtain DataURL string
        var data = event.target.result;
        var req = store.put(data, 'blob');
        req.onerror = function(e) {
            console.log(e);
        };
        req.onsuccess = function(event) {
            console.log('Successfully stored a blob as String.');
        };
    };
    // Convert Blob into DataURL string
    reader.readAsDataURL(blob);
}

截至此时发布,所引用的文档最后更新时间为:Last updated 2019-03-20 UTC.

3
您可以将Blob或File对象转换为ArrayBuffer对象或二进制字符串,然后保存。在从indexedDB读取后,将其转换回Blob即可。
//prepared blob...
blobToBlob2(blob, saveBlob2);

function blobToBlob2(blob, callback){
    var reader = new FileReader();
    reader.readAsArrayBuffer(blob);
    reader.onload = function(e) {
        callback({
            buffer: e.target.result,
            type: blob.type
        });
    };
}

function blob2ToBlob(blob2){
    return new Blob([blob2.buffer],{type:blob2.type});
}

function saveBlob2(blob2){
    //..... code
    var obj = {
        bl:blob2,
        created:tID
    }
    var request = store.add(obj, tID);
    //..... code
}

1
我现在完全退出这个项目,但计划找时间回去(半年前)。blob-indexedDB 的整个重点是保存大型图像(SS),而不是使用 dataURIs 到 chrome.storage。谢谢。 - Wolf War

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接