即使IndexedDB支持存储Blob,但它不支持对Blob进行索引。可转位属性只能是字符串,数字,日期或数组< string |数字|日期>。如果没有,IndexedDB将默默无视地索引该特定对象。
此外,在您的示例代码中,您不是指艺术品表格,而是尝试将blob本身放置,而不是将该文档包含blob属性。
所以,你可以做的是,计算一个散列/内容摘要的blob内容,并存储为一个字符串,你可以使用唯一索引进行索引。
var dbArt = new Dexie('TheDatabase');
dbArt.version(1).stores({
artworks: `
++id,
title,
album,
&artworkDigest` // & = unique index of the digest
});
var artworkBlob = getBlob(image); // get it somehow...
// Now, compute hash before trying to put blob into DB
computeHash(artworkBlob).then(artworkDigest => {
// Put the blob along with it's uniqely indexed digest
return dbArt.artworks.put({
title: theTitle,
album: theAlbum,
artwork: artworkBlob,
artworkDigest: artworkDigest
});
}).then(()=>{
console.log("Successfully stored the blob");
}).catch(error => {
// Second time you try to store the same blob, you'll
// end up here with a 'ConstraintError' since the digest
// will be same and conflict the uniqueness constraint.
console.error(`Failed to store the blob: ${error}`);
});
function computeHash (blob) {
return new Promise((resolve, reject) => {
// Convert to ArrayBuffer
var fileReader = new FileReader();
fileReader.onload =() => resolve(filerReader.result);
fileReader.onerror =() => reject(filerReader.error);
fileReader.readAsArrayBuffer(blob);
}).then (arrayBuffer => {
// Compute Digest
return crypto.subtle.digest("SHA-256", arrayBuffer);
}).then (digest => {
// Convert ArrayBuffer to string (to make it indexable)
return String.fromCharCode.apply(
null, new Uint8Array(digest));
});
};
我也建议存储ArrayBuffer而非BLOB(因为无论如何,我们读的斑点成ArrayBuffer我的样品不显示,但你可以在computeHash()分成两个不同的功能 - 一个将blob读入ArrayBuffer并将另一个读入ArrayBuffer,如果存储ArrayBuffer而不是Blob,则在Safari和其他一些较旧版本的Firefox中会出现较少的错误。
备注:在IndexedDB 2.0中,ArrayBuffers是可索引的(但不是Blob仍然)。但是,我绝不会建议在任何数据库中索引这么大的值。更好的索引摘要。
我还建议使用哈希码 – Josh
我实际上*做*实现哈希方法存储艺术品在一个单独的商店(使用'SparkMD5'),但后来我想也许我不需要它,利用'IndexedDB'索引和唯一约束。但是,没想到'Blob's可能不被支持。 –
是的我的示例代码,这是一个代码转移的错误。固定。 –