介绍
IndexedDB 是一种浏览器内置的低级 API,用于客户端存储大量结构化数据(包括文件/blob)。它的主要特点和用途包括:
-
结构化存储:可以存储复杂的 JavaScript 对象,而不仅仅是简单的键值对
-
索引查询:支持基于索引的高效数据检索
-
大容量存储:通常允许存储比 localStorage 大得多的数据(通常至少 250MB,甚至更多)
-
异步操作:所有操作都是异步的,不会阻塞 UI
-
事务支持:提供事务机制保证数据一致性
-
适用场景:适合存储应用状态、用户生成内容、缓存大量结构化数据等
特性 | 会话缓存 | 本地缓存 | 数据库缓存 |
---|---|---|---|
生命周期 | 会话级 | 持久 | 持久 |
容量 | ~5MB | ~5-10MB | ≥250MB |
操作方式 | 同步 | 同步 | 异步 |
数据结构 | 键值对 | 键值对 | 结构化数据 |
查询能力 | 简单键查询 | 简单键查询 | 复杂索引查询 |
适用场景 | 临时会话数据 | 小量持久数据 | 大量结构化数据 |
博主使用场景:minio的分片上传,先将视频分片存储在indexDB中,用子线程实现分片上传
方法
开启数据库的连接
let db
// 开启的数据库名、版本
const request = indexedDB.open('myDatabase3', 1)
request.onupgradeneeded = function (event) {
db = event.target.result
// 类似 `表`的概念
if (!db.objectStoreNames.contains('myObjectStore')) {
// 创建一个对象存储
const objectStore = db.createObjectStore('myObjectStore', {
// 主键id
keyPath: 'id',
})
// 设置索引,用于后续搜索
objectStore.createIndex('numberIndex', 'number')
}
}
request.onsuccess = function (event) {
db = event.target.result
console.log('数据库已成功打开')
}
request.onerror = function (event) {
console.error('打开数据库失败', event.target.error)
}
查询数据库
const transaction = db.transaction(['video'], 'readonly')
const videoObjectStore = transaction.objectStore('video')
const index = videoObjectStore.index('fileNameIndex')
// 查询所有名字为zhangsan.mp4的记录
const request = index.getAll('zhangsan.mp4')
request.onsuccess = function (event: any) {
const data = event.target.result[0]
}
updateRequest.onerror = function () {
console.error('保存视频之后更新录制结束状态失败')
}
}
// 类似的其他的查询:
// 查询stateIndex 为 1的数据
const index = objectStore.index('stateIndex');
const request = index.getAll(IDBKeyRange.only(1));
// 查询全部
const index = objectStore.index('numberIndex')
const request = objectStore.getAll()
// 获取所有记录
const requestAll = store.getAll();
requestAll.onsuccess = function(event) {
const results = event.target.result;
console.log(results); // 包含所有记录的数组
};
// 获取键范围在1-10的前5条记录
const keyRange = IDBKeyRange.bound(1, 10);
const requestRange = store.getAll(keyRange, 5);
requestRange.onsuccess = function(event) {
const results = event.target.result;
console.log(results); // 最多5条记录的数组
};
新增数据
const transaction = db.transaction(['myObjectStore'], 'readwrite')
const objectStore = transaction.objectStore('myObjectStore')
const data = {
id: 123
}
objectStore.add(data)
修改数据
这个会根据id(主键,也就是创建表的时候设置的keyPath)去更新,
sliceData.state = 0
const transaction = db.transaction(['myObjectStore'], 'readwrite');
const objectStore = transaction.objectStore('myObjectStore');
const updateRequest = objectStore.put(sliceData);
删除数据
const deleteIndexDB = () => {
const transaction = db.transaction(['myObjectStore'], 'readwrite')
const objectStore = transaction.objectStore('myObjectStore')
// 根据主键删除数据
const request = objectStore.delete(1)
request.onsuccess = function (event) {
console.log('数据已删除')
}
request.onerror = function (event) {
console.error('删除数据失败', event.target.error)
}
}
浏览器缓存的三个级别
1. 会话缓存 (Session Storage)
-
生命周期:仅在当前浏览器标签页或窗口有效,关闭标签页/窗口后数据被清除
-
作用域:仅在当前会话中可用,不同标签页即使访问相同网站也有独立的存储
-
容量:通常 5MB 左右
-
API:
window.sessionStorage
-
特点:
-
简单的键值对存储
-
同步操作
-
数据不持久化
-
-
使用场景:临时保存敏感信息、单次会话中的状态保持
2. 本地缓存 (Local Storage)
-
生命周期:持久化存储,除非用户手动清除或代码删除,否则一直存在
-
作用域:同源策略下所有标签页共享
-
容量:通常 5-10MB
-
API:
window.localStorage
-
特点:
-
简单的键值对存储
-
同步操作
-
只能存储字符串,复杂对象需序列化
-
-
使用场景:用户偏好设置、长期需要的小量数据存储
3. 数据库缓存 (IndexedDB/WebSQL)
-
生命周期:持久化存储,除非用户手动清除
-
作用域:同源策略下所有标签页共享
-
容量:通常至少 250MB,甚至可达硬盘空间的 50%
-
API:
window.indexedDB
(WebSQL 已废弃) -
特点:
-
支持结构化数据存储
-
异步操作
-
支持索引和高效查询
-
支持事务
-
-
使用场景:
-
离线应用数据存储
-
大型数据集处理
-
需要复杂查询的应用
-
渐进式 Web 应用(PWA)的核心技术之一
-
对比总结
特性 | 会话缓存 | 本地缓存 | 数据库缓存 |
---|---|---|---|
生命周期 | 会话级 | 持久 | 持久 |
容量 | ~5MB | ~5-10MB | ≥250MB |
操作方式 | 同步 | 同步 | 异步 |
数据结构 | 键值对 | 键值对 | 结构化数据 |
查询能力 | 简单键查询 | 简单键查询 | 复杂索引查询 |
适用场景 | 临时会话数据 | 小量持久数据 | 大量结构化数据 |