indexeddb可直接存储blob、file或arraybuffer二进制数据,无需base64编码,节省空间且高效;支持通过input file、fetch.blob()、canvas.toblob()获取数据,创建objectstore时启用autoincrement,存取时直接使用add()/put()及url.createobjecturl()。

IndexedDB 可以直接存储 Blob、File 或 ArrayBuffer 类型的二进制数据,无需 Base64 编码,这样更节省空间且读写效率更高。
准备数据:获取图片/文件的二进制表示
浏览器中常见的二进制来源有三种:
-
用户选择的文件(如通过
<input type="file">)→ 直接拿到File对象(File是Blob的子类,可直接存) -
通过 fetch 获取的图片/资源 → 调用
response.blob()得到Blob -
Canvas 导出或处理后的数据 → 用
canvas.toBlob()或canvas.toDataURL()(后者需转 Blob,不推荐 Base64)
创建数据库并定义 objectStore(支持二进制)
IndexedDB 原生支持 Blob、File、ArrayBuffer,无需额外序列化。只需在升级时设置合适的 keyPath 或使用自增键:
const request = indexedDB.open('myDB', 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 使用自增键,不依赖文件名等字段做主键
const store = db.createObjectStore('files', { autoIncrement: true });
// 可选:添加索引便于按类型或名称查询
store.createIndex('by-type', 'type', { unique: false });
store.createIndex('by-name', 'name', { unique: false });
};
写入 Blob/File 到数据库
打开事务,调用 add() 或 put(),传入包含二进制数据的对象即可:
function saveFile(file) {
const dbRequest = indexedDB.open('myDB', 1);
dbRequest.onsuccess = (event) => {
const db = event.target.result;
const tx = db.transaction('files', 'readwrite');
const store = tx.objectStore('files');
// 直接存 File 对象(它本身是 Blob)
const record = {
name: file.name,
type: file.type,
size: file.size,
data: file, // ✅ 关键:这里就是 Blob/File
timestamp: Date.now()
};
const addRequest = store.add(record);
addRequest.onsuccess = () => console.log('文件已保存');
};
}
读取并使用二进制数据(如显示图片)
取出记录后,record.data 仍是 Blob,可直接用于 URL.createObjectURL() 或转为 ArrayBuffer 进行处理:
function loadAndShow(id) {
const dbRequest = indexedDB.open('myDB', 1);
dbRequest.onsuccess = (event) => {
const db = event.target.result;
const tx = db.transaction('files', 'readonly');
const store = tx.objectStore('files');
const getRequest = store.get(id);
getRequest.onsuccess = (e) => {
const record = e.target.result;
if (record && record.data instanceof Blob) {
// 方式1:直接显示图片
const url = URL.createObjectURL(record.data);
document.getElementById('img-view').src = url;
// 方式2:读取为 ArrayBuffer(如做图像分析)
const reader = new FileReader();
reader.onload = () => {
const arrayBuffer = reader.result; // Uint8Array 可进一步处理
console.log('已加载为 ArrayBuffer,长度:', arrayBuffer.byteLength);
};
reader.readAsArrayBuffer(record.data);
}
};
};
}
注意:Blob URL 需在不再需要时手动释放(URL.revokeObjectURL(url)),避免内存泄漏。IndexedDB 存储的是引用而非拷贝,但浏览器内部会持久化 Blob 数据,所以即使页面刷新也能读取。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











