瀏覽器儲存全對比:localStorage、IndexedDB、Cache API 與 OPFS
技术架构(更新於 2026年6月8日)
五種瀏覽器儲存機制概覽
現代瀏覽器提供了 5 種主要儲存機制,每種都有不同的設計目標和適用場景:
| 儲存機制 | 資料型別 | 容量上限 | 持久性 | 執行緒存取 |
|---|---|---|---|---|
| localStorage | 字串鍵值對 | ~5-10 MB | 永久 | 僅主執行緒 |
| sessionStorage | 字串鍵值對 | ~5-10 MB | 分頁關閉 | 僅主執行緒 |
| IndexedDB | 結構化資料 + Blob | 數百 MB~無上限 | 永久 | 主執行緒 + Worker |
| Cache API | Request/Response 對 | 與 IndexedDB 共享配額 | 永久 | 主執行緒 + Worker |
| OPFS | 檔案系統 | 與 IndexedDB 共享配額 | 永久 | 僅 Worker(同步) |
localStorage 與 sessionStorage
基本用法
localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme');
localStorage.removeItem('theme');
localStorage.clear();
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
console.log(key, localStorage.getItem(key));
}
關鍵差異
| 特性 | localStorage | sessionStorage |
|---|---|---|
| 生命週期 | 永久儲存 | 分頁關閉即清除 |
| 作用域 | 同源所有分頁共享 | 僅當前分頁 |
| 典型用途 | 使用者偏好、Token | 表單臨時資料、頁面狀態 |
容量偵測
function testLocalStorageQuota() {
const testKey = '__quota_test__';
let data = '';
try {
for (let i = 0; i < 1024; i++) data += 'a'.repeat(1024);
for (let mb = 1; mb < 20; mb++) {
localStorage.setItem(testKey, data.repeat(mb));
}
} catch (e) {
console.log('localStorage 配額已滿');
} finally {
localStorage.removeItem(testKey);
}
}
注意事項
- 同步阻塞:讀寫操作阻塞主執行緒,大資料量影響效能
- 僅存字串:物件需
JSON.stringify/JSON.parse - Storage 事件:同源其他分頁修改時觸發
storage事件
IndexedDB
基本用法
const openRequest = indexedDB.open('myDatabase', 1);
openRequest.onupgradeneeded = (event) => {
const db = event.target.result;
const store = db.createObjectStore('users', { keyPath: 'id' });
store.createIndex('name', 'name', { unique: false });
};
openRequest.onsuccess = (event) => {
const db = event.target.result;
const tx = db.transaction('users', 'readwrite');
const store = tx.objectStore('users');
store.add({ id: 1, name: '張三', email: 'zhang@example.com' });
store.get(1).onsuccess = (e) => {
console.log(e.target.result);
};
};
進階特性
| 特性 | 說明 |
|---|---|
| 交易 | 保證原子性,讀寫分離 |
| 索引 | 支援非主鍵欄位的高效查詢 |
| 游標 | 逐條遍歷大量資料,避免一次性載入 |
| Blob 儲存 | 可直接儲存 File 和 Blob 物件 |
| Worker 存取 | Service Worker 和 Web Worker 中可用 |
使用 idb 函式庫簡化操作
import { openDB } from 'idb';
const db = await openDB('myDatabase', 1, {
upgrade(db) {
db.createObjectStore('users', { keyPath: 'id' });
}
});
await db.put('users', { id: 1, name: '張三' });
const user = await db.get('users', 1);
const allUsers = await db.getAll('users');
await db.delete('users', 1);
Cache API
基本用法
const cache = await caches.open('v1');
await cache.put('/api/data', new Response(JSON.stringify({ foo: 'bar' })));
const response = await cache.match('/api/data');
const data = await response.json();
await cache.delete('/api/data');
與 Service Worker 配合
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((cached) => {
if (cached) return cached;
return fetch(event.request).then((response) => {
const clone = response.clone();
caches.open('v1').then((cache) => {
cache.put(event.request, clone);
});
return response;
});
})
);
});
快取策略對比
| 策略 | 說明 | 適用場景 |
|---|---|---|
| Cache First | 優先快取,快取未命中再請求 | 靜態資源、字型 |
| Network First | 優先網路,失敗回退快取 | API 資料、頻繁更新內容 |
| Stale While Revalidate | 回傳快取同時背景更新 | 非關鍵 API、圖片 |
| Cache Only | 僅從快取讀取 | 離線頁面、預快取資源 |
| Network Only | 僅從網路取得 | 非 GET 請求、即時資料 |
OPFS(Origin Private File System)
基本用法
const root = await navigator.storage.getDirectory();
const fileHandle = await root.getFileHandle('data.bin', { create: true });
const writable = await fileHandle.createWritable();
await writable.write(new Uint8Array([1, 2, 3, 4]));
await writable.close();
const file = await fileHandle.getFile();
const buffer = await file.arrayBuffer();
Worker 中的同步存取
// 在 Worker 中使用同步 OPFS(效能極高)
const root = await navigator.storage.getDirectory();
const fileHandle = await root.getFileHandle('large.bin', { create: true });
const accessHandle = await fileHandle.createSyncAccessHandle();
const buffer = new ArrayBuffer(4);
accessHandle.write(buffer, { at: 0 });
accessHandle.flush();
accessHandle.close();
OPFS 與傳統檔案 API 對比
| 特性 | OPFS | File System Access API |
|---|---|---|
| 使用者授權 | 不需要 | 需要使用者選擇目錄 |
| 可見性 | 瀏覽器內部虛擬檔案系統 | 作業系統真實檔案系統 |
| Worker 同步 | 支援 | 不支援 |
| 持久性 | 永久 | 取決於使用者授權 |
| 適用場景 | 高效能臨時檔案處理 | 檔案編輯器、匯出 |
儲存配額與持久化
查詢可用配額
const estimate = await navigator.storage.estimate();
console.log(`已用: ${(estimate.usage / 1024 / 1024).toFixed(2)} MB`);
console.log(`配額: ${(estimate.quota / 1024 / 1024).toFixed(2)} MB`);
請求持久化
const persisted = await navigator.storage.persist();
if (persisted) {
console.log('儲存已持久化,不會自動清除');
} else {
console.log('儲存可能在壓力下被瀏覽器清除');
}
瀏覽器在儲存壓力下可能自動清除非持久化儲存。呼叫
navigator.storage.persist()可請求持久化權限。
選型決策指南
需要儲存什麼?
├── 簡單鍵值對(< 5MB)
│ ├── 需要跨分頁共享 → localStorage
│ └── 僅當前分頁 → sessionStorage
├── 結構化資料 / 大量記錄
│ └── IndexedDB
├── HTTP 請求/回應快取
│ └── Cache API
└── 大檔案 / 二進位資料 / 高效能讀寫
└── OPFS
實際應用範例
| 場景 | 推薦儲存 | 原因 |
|---|---|---|
| 使用者主題偏好 | localStorage | 簡單鍵值,跨頁面共享 |
| 表單草稿 | sessionStorage | 臨時性,分頁隔離 |
| 離線工具資料 | IndexedDB | 結構化,支援索引查詢 |
| 靜態資源快取 | Cache API | 專為 Request/Response 設計 |
| 影片處理臨時檔案 | OPFS | Worker 同步讀寫,高效能 |
安全注意事項
- XSS 風險:localStorage 可被 XSS 讀取,不要儲存敏感 Token
- HttpOnly Cookie:認證 Token 應使用 HttpOnly + Secure Cookie
- 儲存加密:敏感資料儲存前用 JWT 或 Hash 處理
- Same-Origin 隔離:所有儲存遵循同源策略,跨域不可存取
總結
瀏覽器儲存已從單一的 localStorage 發展為涵蓋鍵值、結構化資料、HTTP 快取和檔案系統的完整體系。選型核心是匹配資料特徵:簡單設定用 localStorage,結構化資料用 IndexedDB,HTTP 快取用 Cache API,高效能檔案處理用 OPFS。
使用 Cookie 解析工具 檢查 Cookie 設定,使用 JWT 工具 驗證 Token 安全性,使用 Hash 工具 對敏感資料進行雜湊處理。
本站提供瀏覽器本地工具,免註冊即可試用 →
#localStorage#sessionStorage#IndexedDB#Cache API#存储对比