前端数据存储方案有哪些?IndexedDB 的优势是什么?
存储方案对比
| 方案 | 容量 | 类型 | 异步 | 适用场景 |
|---|---|---|---|---|
| Cookie | ~4KB | 字符串 | ❌ | 认证凭证 |
| localStorage | ~5MB | 字符串 | ❌ | 简单 KV |
| sessionStorage | ~5MB | 字符串 | ❌ | 会话数据 |
| IndexedDB | ~50MB+ | 结构化 | ✅ | 大量数据 |
| Cache API | ~50MB+ | Response | ✅ | PWA 离线 |
IndexedDB
浏览器端的 NoSQL 数据库,支持事务、索引、游标。
// 打开数据库
const request = indexedDB.open('MyDB', 1)
request.onupgradeneeded = (e) => {
const db = e.target.result
// 创建对象仓库(表)
if (!db.objectStoreNames.contains('users')) {
const store = db.createObjectStore('users', { keyPath: 'id' })
store.createIndex('name', 'name', { unique: false })
}
}
request.onsuccess = (e) => {
const db = e.target.result
// 添加数据
const tx = db.transaction('users', 'readwrite')
const store = tx.objectStore('users')
store.add({ id: 1, name: 'Tom', age: 25 })
// 读取数据
store.get(1).onsuccess = (e) => {
console.log(e.target.result) // { id: 1, name: 'Tom', age: 25 }
}
// 遍历
store.openCursor().onsuccess = (e) => {
const cursor = e.target.result
if (cursor) {
console.log(cursor.value)
cursor.continue()
}
}
}IndexedDB 优势
- 大容量:通常 50MB-1GB(浏览器实现)
- 结构化数据:支持对象、数组、Blob
- 异步 API:不阻塞主线程
- 事务支持:保证数据一致性
- 索引:高效查询
- 同源策略:安全隔离
封装 IndexedDB(Promise 版)
function openDB(name, version, upgradeCallback) {
return new Promise((resolve, reject) => {
const req = indexedDB.open(name, version)
req.onupgradeneeded = (e) => upgradeCallback(e.target.result)
req.onsuccess = (e) => resolve(e.target.result)
req.onerror = (e) => reject(e.target.error)
})
}
function put(db, store, data) {
return new Promise((resolve, reject) => {
const tx = db.transaction(store, 'readwrite')
tx.objectStore(store).put(data)
tx.oncomplete = () => resolve(data)
tx.onerror = () => reject(tx.error)
})
}Cache API(PWA 离线)
// 缓存资源
const cache = await caches.open('v1')
await cache.addAll([
'/',
'/styles.css',
'/app.js'
])
// 从缓存读取
const cached = await caches.match('/styles.css')
// Service Worker 中拦截请求
self.addEventListener('fetch', (e) => {
e.respondWith(
caches.match(e.request).then(cached =>
cached || fetch(e.request)
)
)
})选择建议
- 简单 KV → localStorage
- 大量结构化数据 → IndexedDB
- 离线资源缓存 → Cache API
- 认证 Token →
Cookie (HttpOnly)