localstorage 存储空间已满时唯一可靠判断方式是每次调用 setitem() 时 try-catch 捕获 quotaexceedederror,因浏览器不提供剩余容量 api 且配额不统一(chrome 约 10mb、ios safari 可低至 1mb),必须逐次防护、分层降级并避免 clear() 误删关键数据。

LocalStorage 存储空间已满时,不会提前预警,也不会静默截断,而是在调用 setItem() 的瞬间抛出 QuotaExceededError。因此,判断是否“已满”的唯一可靠方式,就是每次写入都尝试并捕获异常,而不是靠估算或轮询。
必须对每次 setItem 加 try-catch
浏览器不提供 remainingSpace 这类 API,也无法跨平台统一配额值(Chrome/Edge 约 10 MB,Firefox 5–10 MB,iOS Safari 可能低于 1 MB,X5 内核甚至不足 1 MB)。所以:
- 不能只在页面初始化时检查一次容量
- 不能依赖
"x".repeat(5e6)类粗暴试探,易卡死或误判 - 每次
localStorage.setItem(key, value)都要包裹 try-catch - 测试用极小数据(如
"test")更稳妥,避免单次写入过大掩盖真实余量
精准识别 QuotaExceededError
不同浏览器抛错形式不一:Chrome/Firefox/Edge 多为 name === "QuotaExceededError";旧版 Safari 可能是 name === "NS_ERROR_DOM_QUOTA_REACHED" 或 code === 1014;部分老环境用 code === 22。推荐封装判定函数:
function isQuotaExceededError(err) {
return err instanceof DOMException &&
(err.name === 'QuotaExceededError' ||
err.name === 'NS_ERROR_DOM_QUOTA_REACHED' ||
err.code === 22 ||
err.code === 1014);
}
使用时直接嵌入逻辑:
- 捕获到该错误,说明物理上限已达,需立即熔断
- 其他异常(如隐私模式禁用、key 为空)不应吞掉,应原样抛出
溢出后安全降级与清理
严禁调用 localStorage.clear() —— 它会无差别删除 token、主题设置、登录态等关键数据。应分层响应:
- 非关键数据(如草稿、滚动位置):静默丢弃,可提示用户“本地缓存已满,当前未持久化”
- 关键数据(如用户信息、token):优先降级到
sessionStorage(同源独立配额),再 fallback 到内存缓存 + 下次启动重拉 - 轻量清理策略:只删带
_temp、_draft、cache_前缀的 key;或解析 value 后按expiresAt/createdAt清除过期项;解析失败的脏数据也可直接移除 - 清理后建议重试本次写入,而非直接放弃
从源头控制,比事后补救更有效
反复清理是治标。真正降低溢出概率,要精简写入内容本身:
- 只存必要字段:用户数据留
id、name、avatarUrl、expiresAt,去掉冗余嵌套 - 禁存 base64 图片、HTML 片段、二进制 blob —— 改用 URL 引用
- 长文本(日志、草稿)用
lz-string压缩,纯文本压缩率常达 60%+ - 写入前粗略估算字节数:
new TextEncoder().encode(JSON.stringify(value)).length,叠加已有用量预判 - 超大结构数据(如文件列表、离线消息)直接降级到
IndexedDB,可用localForage封装简化操作
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











