← 中文资源

简体中文版本

DOMException QuotaExceededError — 存储已满

通过测量用量、清理陈旧条目并申请持久化存储,修复 localStorage 与 IndexedDB 的 QuotaExceededError。

阅读英文原文

症状

本篇调试指南针对“DOMException QuotaExceededError — 存储已满”。内容涵盖可观察的症状、可复现的诊断路径、根本原因、具体修复方式,以及如何验证修复并防止回归。

可观察到的症状包括:

  • DOMException: Storage 的 setItem 失败,设置的值为超出配额
  • localStorage 写入先是成功,随后突然抛错
  • IndexedDB 事务以 QuotaExceededError 中止

诊断

先在隔离环境中复现故障,再按顺序执行以下检查,逐步缩小范围。

步骤 1

console.log(JSON.stringify(localStorage).length)

可近似估算已用字节;与约 5MB 限制对比以确认是否饱和。

步骤 2

await navigator.storage.estimate()

返回 usage 与 quota,显示该源距上限还有多少。

常见诱因(按出现频率排序):

  • 源存储桶已满(localStorage 每源约 5MB)
  • 把过大值(如 base64 图片)直接存入
  • 隐私模式下部分浏览器大幅限制容量

根因

每个源都有存储配额。localStorage、sessionStorage 与 IndexedDB 共享该配额,超出限制时写入会抛 QuotaExceededError,而非静默截断数据。

修复

仅存储必要数据,大对象放 IndexedDB 或服务端,按 LRU 清理陈旧条目,并调用 navigator.storage.persist() 减少意外清除。

注意:静默回退到内存会在刷新后丢数据;始终应上报或处理配额错误。

async function safeSet(key, value) {
  try {
    localStorage.setItem(key, value);
  } catch (err) {
    if (err.name === 'QuotaExceededError' || err.name === 'NS_ERROR_DOM_QUOTA_REACHED') {
      evictOldest();       // drop stale keys, then retry once
      localStorage.setItem(key, value);
    } else throw err;
  }
}

// prefer persistent storage to avoid surprise eviction
if (navigator.storage?.persist) await navigator.storage.persist();

验证

持续写入至上限并确认清理逻辑避免了抛错;检查 navigator.storage.estimate 报告用量低于配额。

修复后补充一条回归测试,复现原始症状,防止问题再次出现。

这类故障通常是环境问题而非纯逻辑错误,因此在缺陷记录中应写明完整命令、环境变量与工作目录。请用最小的脚本复现,待最小用例清楚后再扩大范围。为这类故障准备一份简短的排查清单,能显著减少下次排障时间。