浏览器本地存储
现代浏览器提供了多种本地存储方案,各有优劣,适用于不同的场景。
1. 存储方案对比
| 特性 | Cookie | LocalStorage | SessionStorage | IndexedDB |
|---|---|---|---|---|
| 容量 | 小 (4KB) | 中 (5-10MB) | 中 (5-10MB) | 大 (>250MB) |
| 生命周期 | 设置的 Expires | 永久 (除非手动删除) | 会话级 (关闭 Tab 失效) | 永久 (除非手动删除) |
| 网络传输 | 每次请求都会带上 | 不参与网络传输 | 不参与网络传输 | 不参与网络传输 |
| API 易用性 | 难 (document.cookie) | 易 (setItem/getItem) | 易 (setItem/getItem) | 难 (异步/事务) |
| 适用场景 | 身份认证 (Token/SessionId) | 持久化配置、简单数据 | 临时表单数据、一次性状态 | 大量结构化数据、离线应用 |
2. Cookie
最初设计用于在客户端和服务器之间保持状态(HTTP 是无状态的)。
特点:
- 自动发送:同域下每次 HTTP 请求都会携带,流量消耗大。
- HttpOnly:设置后 JS 无法读取,防止 XSS。
- Secure:只能通过 HTTPS 传输。
- SameSite:限制跨站传输,防止 CSRF。
操作:
javascript
// 读取
document.cookie; // 返回字符串 "key1=val1; key2=val2"
// 写入 (一次写一个)
document.cookie = "username=John; expires=...; webpath=/";3. Web Storage (Local / Session)
HTML5 引入,专门用于浏览器端数据存储。
区别:
LocalStorage:数据持久存储,除非主动删除。由同源的窗口共享。SessionStorage:数据仅在当前会话有效。关闭标签页即清除。不共享(即使是同源的两个 Tab 也是隔离的)。
操作:
javascript
localStorage.setItem('key', 'value');
const val = localStorage.getItem('key');
localStorage.removeItem('key');
localStorage.clear();
// 监听 storage 事件 (当其他 Tab 修改数据时触发,实现跨 Tab 通信)
window.addEventListener('storage', (e) => {
console.log(e.key, e.newValue);
});4. IndexedDB
一个运行在浏览器中的非关系型数据库(NoSQL)。
特点:
- 大容量:通常不少于 250MB,甚至可以使用硬盘剩余空间的 50%。
- 结构化:支持存储对象、文件、Blob 等。
- 索引:支持高性能搜索。
- 事务:支持事务操作,保证数据一致性。
- 异步:API 大多是异步的,不会阻塞主线程。
基本流程:
javascript
// 1. 打开数据库
const request = indexedDB.open("MyDatabase", 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// 2. 创建对象仓库 (类似表)
const store = db.createObjectStore("users", { keyPath: "id" });
// 创建索引
store.createIndex("name", "name", { unique: false });
};
request.onsuccess = (event) => {
const db = event.target.result;
// 3. 开启事务
const transaction = db.transaction(["users"], "readwrite");
const store = transaction.objectStore("users");
// 4. 添加数据
store.add({ id: 1, name: "Alice", age: 25 });
};应用场景:
- 离线笔记应用(Notion 类)。
- 大型编辑器(Figma 类)。
- 缓存大量的 API 响应数据。
5. 总结
- 敏感数据(Token):建议放内存或
Cookie (HttpOnly)。 - 简单配置/缓存:使用
LocalStorage。 - 大文件/复杂数据:使用
IndexedDB。 - 尽量不要用 Cookie 存储非认证相关的数据(减少流量)。