浏览器存储全对比: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
  • 存储加密:敏感数据存储前用 JWTHash 处理
  • Same-Origin 隔离:所有存储遵循同源策略,跨域不可访问

总结

浏览器存储已从单一的 localStorage 发展为覆盖键值、结构化数据、HTTP 缓存和文件系统的完整体系。选型核心是匹配数据特征:简单配置用 localStorage,结构化数据用 IndexedDB,HTTP 缓存用 Cache API,高性能文件处理用 OPFS。

使用 Cookie 解析工具 检查 Cookie 配置,使用 JWT 工具 验证 Token 安全性,使用 Hash 工具 对敏感数据进行哈希处理。

本站提供浏览器本地工具,免注册即可试用 →

#localStorage#sessionStorage#IndexedDB#Cache API#存储对比