在现代 Web 应用中,本地存储是实现离线功能和提升用户体验的关键技术。随着 Web 应用变得越来越复杂,开发者需要了解浏览器提供的各种本地存储方案,以便为不同场景选择最合适的存储方式。
一、浏览器本地存储方案概览
浏览器提供了多种本地存储方案,每种方案都有其适用场景和限制:
| 存储方案 | 存储容量 | 数据类型 | 是否持久化 | 主要用途 |
|---|---|---|---|---|
| localStorage | 5MB | 字符串 | 是 | 用户偏好设置、会话数据 |
| sessionStorage | 5MB | 字符串 | 否 | 临时会话数据 |
| IndexedDB | 无限制 | 结构化数据 | 是 | 离线数据、大量数据存储 |
| Cache API | 无限制 | HTTP 请求/响应 | 是 | 离线缓存、资源缓存 |
二、localStorage:简单键值存储
localStorage 是最简单的本地存储方案,提供键值对存储,数据在页面刷新后仍然保留。
基本用法
// Store data
localStorage.setItem('username', 'Zhang San');
localStorage.setItem('settings', JSON.stringify({ darkMode: true, fontSize: 16 }));
// Read data
const username = localStorage.getItem('username');
const settings = JSON.parse(localStorage.getItem('settings'));
// Remove data
localStorage.removeItem('username');
// Clear all data
localStorage.clear();
// Get all keys
const keys = Object.keys(localStorage);
适用场景
- 用户偏好设置(主题、字体大小等)
- 简单的用户会话数据
- 表单自动填充数据
- 应用配置参数
注意事项
- 仅支持字符串类型,复杂数据需使用
JSON.stringify()和JSON.parse() - 存储容量约 5MB,超出会抛出异常
- 数据会随 HTTP 请求发送(可能导致安全问题)
- 同步操作,大量数据会阻塞主线程
三、sessionStorage:临时会话存储
sessionStorage 与 localStorage API 相同,但数据只在当前会话有效,关闭浏览器标签页后数据会被清除。
基本用法
// Store session data
sessionStorage.setItem('currentPage', '/dashboard');
// Read data
const currentPage = sessionStorage.getItem('currentPage');
// Auto-cleared after session ends
适用场景
- 临时表单数据(防止刷新丢失)
- 当前页面状态
- 敏感数据(不需要持久化)
四、IndexedDB:大规模结构化存储
IndexedDB 是浏览器提供的事务型数据库系统,支持存储大量结构化数据,是 PWA 离线应用的核心技术。
基本用法
// Open database
const request = indexedDB.open('myDatabase', 1);
request.onupgradeneeded = (event) => {
const db = event.target.result;
// Create object store
const store = db.createObjectStore('users', { keyPath: 'id' });
// Create index
store.createIndex('name', 'name', { unique: false });
};
request.onsuccess = (event) => {
const db = event.target.result;
// Add data
const transaction = db.transaction(['users'], 'readwrite');
const store = transaction.objectStore('users');
store.add({ id: 1, name: 'Zhang San', age: 28 });
transaction.oncomplete = () => {
console.log('Data added successfully');
};
};
高级查询
// Query using index
const transaction = db.transaction(['users'], 'readonly');
const store = transaction.objectStore('users');
const index = store.index('name');
// Get all users named "Zhang San"
const request = index.getAll('Zhang San');
request.onsuccess = (event) => {
const users = event.target.result;
console.log(users);
};
// Range query
const range = IDBKeyRange.bound(20, 30);
const ageRequest = store.index('age').getAll(range);
适用场景
- 离线应用数据存储
- 大量结构化数据(如用户列表、商品数据)
- 需要索引和事务支持的复杂查询
- 图片、文件等二进制数据存储
💡 提示:IndexedDB 是异步操作,不会阻塞主线程。建议使用封装库如 localForage 或 idb 来简化操作。
五、Cache API:资源缓存
Cache API 主要用于缓存 HTTP 请求和响应,是 Service Worker 实现离线应用的关键。
基本用法
// Cache resources in Service Worker
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('v1').then((cache) => {
return cache.addAll([
'/',
'/index.html',
'/styles.css',
'/app.js'
]);
})
);
});
// Intercept requests and return cached responses
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
// Return cached or fetch from network
return response || fetch(event.request);
})
);
});
六、最佳实践建议
1. 根据数据类型选择存储方案
- 简单键值对、配置数据 →
localStorage - 临时会话数据 →
sessionStorage - 大量结构化数据 →
IndexedDB - 静态资源缓存 →
Cache API
2. 数据序列化
对于 localStorage 和 sessionStorage,存储复杂数据时要注意序列化和反序列化:
// Serialize before storing
const data = { name: 'Zhang San', age: 28 };
localStorage.setItem('user', JSON.stringify(data));
// Deserialize after reading
const user = JSON.parse(localStorage.getItem('user'));
3. 错误处理
try {
localStorage.setItem('key', 'value');
} catch (e) {
if (e.name === 'QuotaExceededError') {
console.warn('Storage quota exceeded');
// Clean up old data or notify user
}
}
4. 数据版本管理
对于 IndexedDB,使用版本号管理数据库结构变化:
const request = indexedDB.open('myDatabase', 2);
request.onupgradeneeded = (event) => {
const db = event.target.result;
const oldVersion = event.oldVersion;
if (oldVersion < 2) {
// Add new fields or indexes
const store = db.transaction.objectStore('users');
store.createIndex('email', 'email', { unique: true });
}
};
七、总结
选择合适的本地存储方案取决于数据的类型、大小和使用场景:
- localStorage:简单、同步,适合小量配置数据
- sessionStorage:临时存储,适合会话数据
- IndexedDB:异步、事务型,适合大量结构化数据
- Cache API:资源缓存,适合离线应用
在实际开发中,通常会组合使用多种存储方案,以充分发挥各自的优势,为用户提供更好的离线体验和性能。