必须对每次 localstorage.setitem() 操作显式使用 try-catch,这是应对 quotaexceedederror 的唯一可靠方式;浏览器不提供剩余空间接口,错误仅在写入瞬间抛出,不捕获会导致逻辑中断甚至白屏,且 localstorage.length 无法反映真实字节数,跨浏览器配额差异大(chrome/firefox 5–10mb,safari ios 可低至 2.5mb),隐身模式下可能直接禁用。

必须对每次 localStorage.setItem() 操作显式使用 try-catch,这是应对 QuotaExceededError 的唯一可靠方式。浏览器不会提前预警容量将尽,也不会提供剩余空间查询接口,错误只在写入瞬间抛出——不捕获就会中断逻辑,甚至导致白屏或功能失效。
为什么不能只检查一次或依赖 length
localStorage.length 仅返回键的数量,完全无法反映实际字节数;Unicode 字符、JSON 序列化开销、浏览器内部存储结构都会显著影响真实占用。不同浏览器配额差异大(Chrome/Firefox 约 5–10MB,Safari iOS 可能低至 2.5MB),且隐身模式下可能直接禁用,这些都无法通过静态判断预知。
标准 try-catch 写法与关键细节
- 每次
setItem都要包裹,不是只在初始化或关键节点做一次 - 必须检查
e.name === 'QuotaExceededError',而非仅靠instanceof DOMException,因部分环境抛出的是普通Error - 写入值务必先
JSON.stringify(),否则对象、布尔、数字等类型会变成"[object Object]"或"true",后续解析失败 - 捕获后不要直接丢弃数据,应触发清理逻辑(如按前缀删除缓存项),再重试本次写入
探路式预判(可选增强)
可在正式写入前用轻量试探操作粗略判断是否临近上限:
- 执行
localStorage.setItem('probe', 'x'),成功后立即removeItem('probe') - 若试探失败,说明已满或不可用,可提前降级到内存 Map 或 sessionStorage
- 注意:试探本身也要
try-catch,不能假设它一定安全
降级与 fallback 路径
捕获到配额错误后,需按优先级提供后备方案:
- 关键用户状态(如登录态、主题偏好)优先保留,清理临时缓存(如
app_cache_*前缀的 key) - 非关键数据可暂存内存
Map,页面生命周期内有效 - 支持 IndexedDB 的场景,可拆分批量写入为小批次(如每次 50 条),并自动清理过期记录
- 极端情况(如 Safari 无痕模式),将必要状态序列化后附在 URL hash 中,或利用
beforeunload事件尝试存入sessionStorage











