localStorage 无“是否已满”API,需用试探写入+QuotaExceededError捕获判断容量;主流容量5–10MB,推荐封装setItemWithCleanup自动清理,配合预估大小、统一管理和预防性策略提升可靠性。

localStorage 没有直接提供“是否已满”的 API,但可以通过尝试写入数据并捕获异常来判断容量是否耗尽。主流浏览器的 localStorage 容量通常为 5–10 MB(具体因浏览器和隐私模式而异),超出时会抛出 QuotaExceededError。关键不是预先计算剩余空间,而是用“试探写入 + 异常处理”机制触发清理逻辑。
用 try-catch 检测写入失败并触发清理
这是最可靠、兼容性最好的方式:尝试存入一小段测试数据,若失败,说明接近或已达上限,此时执行自定义清理策略。
- 不要依赖
localStorage.length或JSON.stringify(localStorage).length—— 这无法反映真实字节数,且序列化可能本身触发异常 - 写入内容应足够小(如
"test"),避免因单次写入过大误判 - 清理前先备份关键字段(如用户偏好、登录态 token),防止误删
实现一个安全的 setItemWithCleanup 方法
封装写入逻辑,自动处理容量不足场景:
function setItemWithCleanup(key, value) {
try {
localStorage.setItem(key, value);
} catch (e) {
if (e.name === 'QuotaExceededError') {
console.warn('localStorage 已满,启动清理');
cleanupStorage();
// 清理后重试一次
localStorage.setItem(key, value);
} else {
throw e;
}
}
}
<p>function cleanupStorage() {
// 示例:删除 30 天前的过期项(需提前约定时间戳字段格式)
const now = Date.now();
for (let i = localStorage.length - 1; i >= 0; i--) {
const key = localStorage.key(i);
const item = localStorage.getItem(key);
try {
const parsed = JSON.parse(item);
if (parsed.<strong>expires && parsed.</strong>expires < now) {
localStorage.removeItem(key);
}
} catch (e) {
// 非 JSON 格式或损坏数据,可选择跳过或删除
continue;
}
}
// 可选:按 LRU 策略删除最久未用项(需额外维护访问时间记录)
}预防性策略比被动清理更有效
单纯等报错再清理体验较差。建议结合以下做法降低风险:
- 写入前估算大小:用
new TextEncoder().encode(str).length获取 UTF-8 字节长度,对大对象做粗略预判(注意:实际占用略大于此值,因 key 名、JSON 开销等) - 统一管理存储:用封装类(如
StorageManager)接管所有读写,内置容量监控与淘汰逻辑 - 敏感数据优先使用 sessionStorage 或内存缓存;非关键日志、埋点数据可降级到 cookie 或直接丢弃
- 在页面加载或空闲时主动调用轻量清理(如清除临时搜索历史),避免集中爆满
注意浏览器差异与边界情况
某些环境会让检测更复杂,需特别留意:
- 无痕/隐私模式下容量可能骤降至 0–2 MB,甚至禁用 localStorage(此时
localStorage为 null) - Safari 在 iOS 11+ 对第三方上下文(如 iframe)大幅限制 localStorage,可能静默失败
- 部分 Android WebView 不抛
QuotaExceededError,而是静默截断,需配合写入后读取校验 - 清理时避免遍历中调用
removeItem导致索引偏移,推荐倒序遍历或收集 key 后批量删除

















