localstorage无统一容量上限,实际空间取决于浏览器、平台与系统状态;超限时setitem()同步抛出quotaexceedederror;须用textencoder计算utf-8字节长度并预留余量;应试探写入+异常捕获双保险;清理须按前缀、过期、损坏精准剔除;大数据应降级至indexeddb或分片存储。

localStorage 没有统一、固定的容量上限,实际可用空间取决于浏览器型号、操作系统、设备内存状态,甚至用户隐私设置。所谓“5MB”只是常见参考值,并非标准——Chrome/Edge 桌面版通常在 5–10 MB 之间,Firefox 约 5 MB,而 iOS Safari 在旧版本中曾低至 1 MB,开启防跟踪策略时可能直接禁用或归零。
超额报错的本质是 QuotaExceededError
当调用 localStorage.setItem() 超出当前可用配额时,浏览器不会静默丢弃数据,也不会自动清理旧项,而是**同步抛出 QuotaExceededError 异常**。这是唯一可靠的“空间告罄”信号,没有提前查询剩余容量的 API,也不能靠 localStorage.length 或 JSON.stringify(localStorage).length 准确估算。
- 每次写入都必须用
try...catch包裹,否则异常会中断脚本执行,导致功能失效甚至白屏 - 不要依赖“测试一次就一劳永逸”的检测逻辑;不同标签页、不同时间点的可用空间可能动态变化
- 试探写入建议用极小值(如
"test"),避免因单次写入过大误判为容量不足
写入前预估字节长度更可控
JavaScript 字符串内部用 UTF-16 编码,但 localStorage 实际按 UTF-8 字节存储。直接用 .length 会高估(中文字符算 2 字符,UTF-8 却占 3 字节),也低估(emoji 可能占 4 字节)。正确做法是:
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
- 使用
new TextEncoder().encode(str).length获取真实 UTF-8 字节数 - 对大对象(如 base64 图片、长日志)写入前强制拦截:超过 50 KB 直接拒绝存 localStorage
- 关键状态(如 token、主题)单独标记并预留至少 200 KB 安全空间,确保登录态等核心逻辑不被挤掉
清理不能靠 clear(),要分级精准剔除
捕获到 QuotaExceededError 后,应立即触发清理,但不是清空全部:
- 按 key 前缀分类管理(如
cache_、draft_、temp_),只删对应类目 - 存储时主动附加元信息,例如:
{ value: "...", expires: 1745000000000, lastUsed: Date.now() },清理时优先淘汰过期或最久未用项 - 删除前做 JSON 校验,跳过已损坏项:
try { JSON.parse(localStorage.getItem(key)) } catch(e) { localStorage.removeItem(key); } - 清理后重试原写入操作,形成“试探→失败→清理→重试”闭环
长期策略:源头降压 + 分级降级
清理是补救,预防才是重点:
- 非必要不存大文本或二进制数据;结构化大数据迁移到 IndexedDB(容量可达数百 MB,支持索引与事务)
- 敏感或临时数据改用
sessionStorage,关闭即释放,不占持久空间 - 对 JSON 状态启用轻量压缩(如 lz-string),实测可节省 60%–80% 空间,解压开销可控
- 所有读写统一走封装类(如
StorageManager),内置字节估算、异常捕获、自动降级和用量上报










