浏览器本地存储有硬性配额限制,超限抛QuotaExceededError;需用try-catch捕获、预估容量、分片写入、精准清理、谨慎压缩,并注意跨浏览器配额计算差异。

浏览器本地存储不是“无限硬盘”,超限会直接抛 QuotaExceededError,导致写入中断、页面逻辑卡死——这不是代码 bug,是配额硬限制在起作用。
localStorage 写入失败时怎么捕获和预判
不能等报错才处理,得提前试探或估算。Chrome 桌面约 10 MB,Safari iOS 可能仅 2.5 MB,setItem 超限时不会返回 false,而是抛异常。
- 必须用
try { localStorage.setItem(k, v) } catch (e) { if (e.name === 'QuotaExceededError') { /* 降级 */ } } -
localStorage.length没用——它只返回 key 的数量,不反映字节体积 - 粗略估算当前占用:
encodeURIComponent(JSON.stringify(localStorage)).length(注意:Unicode 字符如中文会占多个字节) - 写入前可先试写一段 1MB 字符串,捕获异常判断是否濒临满载
IndexedDB 溢出时事务提交失败怎么应对
QuotaExceededError 或 AbortError 常出现在 transaction.commit() 阶段,尤其批量写入时。它不像 localStorage 那样“一写就崩”,但失败更隐蔽。
- 打开数据库时监听
upgradeneeded和blocked事件,event.newVersion === null往往意味着打开失败,可能因空间不足 - 批量写入务必分片,例如每次
add()50 条,失败后重试小批次,避免整批回滚 - 自动触发清理策略:按时间戳删 >7 天的旧记录,或按使用频率保留 top N 条
- 不要假设 IndexedDB “肯定比 localStorage 大”——某些 Android WebView 下初始配额可能仅 50 MB
怎么安全清理 localStorage 里不用的 key
localStorage.clear() 是高危操作,会连 token、用户设置一起清掉。必须按前缀或语义精准清理。
- 给缓存 key 统一加前缀,如
app_cache_search_、temp_form_draft_,清理时遍历key(i)匹配前缀再删 - 禁用
for...in遍历localStorage——它会污染原型链属性,不可靠 - 删除前做 JSON 校验:
try { JSON.parse(localStorage.getItem(k)) } catch(e) { localStorage.removeItem(k); },顺手清理损坏项 - 清理后手动触发
window.dispatchEvent(new Event('storage'))(仅通知其他 tab,本页收不到)
大体积数据该不该压缩再存进 localStorage
压缩能延缓溢出,但 JS 解压本身有开销,移动端尤其明显。不是所有值都值得压。
- 纯文本类(日志、搜索历史、表单草稿)收益明显;JWT、布尔字符串(
"true")压缩后反而更大 - 优先做轻量优化:
JSON.stringify(obj, null, 0)去空格,省 15–30% 体积 - 真要压缩,选
pako.deflate()+atob()编码,但注意 iOS Safari 对Uint8Array支持从 iOS 13 才稳定 - 必须存压缩标识和原始长度,比如
{"z":1,"d":"eJ..."},否则未来调试或升级时无法识别格式
最常被忽略的一点:不同浏览器对同一 origin 的配额计算方式不一致——Chrome 算的是 UTF-16 字节数,Safari 算的是 UTF-8,同样一段中文,估算值可能差一倍。别信“我测过 9.8 MB 没问题”,换台 iPhone 就可能崩。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











