本文,我们来探讨前端浏览器中的存储 - IndexedDB
。
浏览器的缓存
浏览器的 Application
下面有如图存储方式 👇
以上是谷歌浏览器的截图,其版本是 134.0.6998.89(正式版本) (x86_64)
老生常谈的存储 Cookies
, LocalStorage
和 SessionStorage
有如下特点:
名称 | 特点 | 限制 | 用途 |
---|---|---|---|
Cookies | 跟随 HTTP 请求自动发送到服务器。可以设定过期时间 | 存储空间小(通常为 4KB) | 适用于客户端和服务端之间传递小数据,比如会话标志 |
LocalStorage | 关闭浏览器也不会丢失数据 | 存储空间有限(通常为5MB),只能存储字符串类型的数据 | 适用于需要持久化存储的数据,如用户偏好 |
SessionStorage | 数据在浏览器会话期存储 | 存储空间有限(通常为5MB),只能存储字符串类型的数据 | 适合临时存储数据,比如表单数据 |
之前浏览器有两个数据库存储 WebSQL
和 IndexedDB
,但是 WebSQL
未能成为正式的 Web
标准,并逐渐被 IndexedDB
替代。
认识 IndexedDB
IndexedDB
在现代主流的浏览器上的表现很好,基本没啥兼容性问题。如果是在业务型特定浏览器 webkit
内核上,更不用关心兼容性的问题。
当需要在浏览器中存储大量结构化数据,IndexedDB
提供了一个事务性的键值存储系统,允许我们在客户端存储和检索数据。它适用于需要离线存储和处理复杂数据的 WEB
应用。
IndexedDB
主要有以下的特点:
- 异步操作:
IndexedDB
的所有操作都是一步的,这意味着它不会阻塞主线程
,从而提高应用的响应速度。 - 事务支持:
IndexedDB
支持事务操作,确保数据的一致性和完整性。事务可以是只读或者读写的。 - 键值存储:
IndexedDB
中数据以键值对的形式存储,类似于NoSQL
数据库。每个存储对象Object Store
都有一个主键,用于唯一标识记录。 - 索引:
IndexedDB
可以为对象存储创建索引,以便快速查询数据。索引可以是唯一的或非唯一的。 - 版本控制:
IndexedDB
支持数据库版本控制,允许我们在升级数据库时进行结构性更改。 - 存储限制:
IndexedDB
存储空间比较大。这取决不同浏览器的实现。在Google Chrome
中,IndexedDB
默认存储配额通常为60%
的可用磁盘空间。存储空间比localStorage
大得多。
IndexedDB 使用
下面,我们将通过代码案例来讲解怎么去使用 IndexedDB
。
// 定义数据库
let db: IDBDatabase;
// 打开数据库
const request = indexedDB.open("requestDatabase");
// 创建表名
const storeName = "jimmyStore";
export interface IIndexedDBDataItem {
id: string;
value: string;
}
// 数据库打开错误
request.onerror = (event) => {
console.error("无法打开数据库");
}
// 成功打开
request.onsucess = (event: Event) {
db = (event.target as IDBOpenDBRequest).result;
console.log("数据库打开成功", db);
}
// 数据库升级(第一次新建库也会触发,因为数据库从无到有算一次升级)
request.onupgradeneeded = async (event: IDBVersionChangeEvent) => {
db = (event.target as IDBOpenDBRequest).result;
if (!db.objectStoreNames.contains(storeName)) {
// 创建数据库存储名称
db.createObjectStore(storeName, { keyPath: "id" });
}
}
// 添加数据
export const addIndexedDBData = (data: IIndexedDBDataItem): Promise<void> => {
return new Promise((resolve, reject) => {
// 创建事务
const transaction = db.transaction([storeName], "readwrite");
const objectStore = transaction.objectStore(storeName);
const request = objectStore.add(data);
request.onsucess = () => {
resolve();
}
request.onerror = (event) => {
reject(event);
}
})
}
// 删除存在的数据
export const deleteIndexedDBData = (id: string): Promise<void> => {
return new Promise((resolve, reject) => {
const transaction = db.transaction([storeName], "readwrite");
const objectStore = transaction.objectStore(storeName);
const request = objectStore.delete(id); // 如果是删除全部的数据,我们可以使用 objectStore.clear() 来实现
request.onsucess = () => {
resolve();
}
request.onerror = () => {
reject(event);
}
});
}
// 获取 indexedDB 数据
export const getIndexedDBData = (id: string): Promise<IIndexedDBDataItem | undefined> => {
return new Promise((resolve, reject) => {
const transaction = db.transaction([storeName], "readonly");
const objectStore = transaction.objectStore(storeName);
const request = objectStore.get(id);
request.onsucess = () => {
resolve();
}
request.onerror = () => {
reject(event);
}
})
}
上面,我们实现了对数据库数据的写入,删除和获取。以谷歌为例,在 window 上,数据会被保存在 C:\Users\Jimmy(当前用户)\AppData\Local\Google\Chrome\User Data\Default\IndexedDB
下面 👇