navigator.storage.estimate() 返回的 quota 是理论上限而非剩余配额,实际可用空间受系统、浏览器策略等影响,可能为 0 或 undefined;usage 与 quota 均为瞬时快照,不可实时反映存储状态。

navigator.storage.estimate() 返回的 quota 不是“剩余配额”
很多人调用 navigator.storage.estimate() 后看到返回对象里有 quota 字段,就直接拿它减去 usage 当作“还能存多少”,这是错的。quota 是浏览器给该源(origin)分配的**理论上限**,但实际可用空间受系统限制、私有模式、存储策略(如 LRU 清理)影响,甚至可能为 0 或 undefined(比如 Safari 完全不支持该字段)。真正能反映“当前还能写多少”的,是 quota - usage 的**参考值**,而非保障值。
- Chrome / Edge(基于 Chromium):通常返回较合理的
quota,但若设备磁盘已满或用户禁用持久化存储,quota可能骤降至几 MB - Firefox:
quota恒为undefined,只提供usage;你无法通过此 API 推算剩余空间 - Safari:整个
navigator.storage在非 PWA 场景下受限严重,estimate()可能抛出SecurityError或返回空对象
必须先检查 navigator.storage 是否可用且已授权
未满足条件时直接调用会静默失败或报错。关键前置判断不是“有没有这个 API”,而是“当前上下文是否被允许使用持久化存储”:
- 仅在
https://或localhost下可用(http://域名一律拒绝) - 需用户与页面有交互(如点击)后才能申请持久化权限,否则
navigator.storage.persisted()返回false,且estimate()结果不可靠 - 部分浏览器(如 Firefox)要求站点被“安装为 PWA”或用户手动开启“网站数据设置”中的存储权限
实操建议:在按钮点击回调中执行以下逻辑
button.addEventListener('click', async () => {
if ('storage' in navigator && 'estimate' in navigator.storage) {
try {
const persisted = await navigator.storage.persisted();
if (!persisted) {
// 触发权限申请(仅 Chromium 系有效)
await navigator.storage.persist();
}
const { usage, quota } = await navigator.storage.estimate();
console.log('已用:', usage, '总配额:', quota, '估算剩余:', quota ? quota - usage : 'N/A');
} catch (err) {
console.warn('获取存储信息失败:', err.name); // 常见:SecurityError、TypeError
}
}
});
navigator.storage.estimate() 的结果是快照,不实时更新
返回的 usage 和 quota 是调用时刻的瞬时值,不会随 IndexedDB 写入、Cache API 添加缓存而自动刷新。尤其 usage 包含所有存储 API 占用(IndexedDB、Cache API、Service Worker 缓存、甚至部分浏览器的 localStorage 副本),但统计延迟可达数秒到数分钟(Firefox 尤其明显)。
- 不要用它做高频轮询(如每秒查一次),既无意义又触发额外开销
- 若需响应式监控,应结合业务动作:例如在
IDBTransaction.oncomplete后主动重查,或监听storage事件(仅对 localStorage 生效) - 注意
usage可能包含已被标记删除但尚未清理的数据(如 IDBObjectStore.clear() 后未 commit)
替代方案:用 cacheStorage.match() + Response.arrayBuffer() 间接试探
当 navigator.storage.estimate() 不可用或返回 undefined 时,没有标准 API 能精确获取“剩余磁盘空间”。但可借助 Cache API 的写入失败行为做保守估算:
- 创建一个临时 cache,尝试写入不同大小的 blob(如 1MB、5MB、10MB)
- 捕获
QuotaExceededError出现的位置,反推大致可用空间下限 - 注意:这会真实占用空间,务必在
finally中调用cache.delete()清理
这不是优雅解法,但在 Safari 或 Firefox 中,它是唯一能给出“还能不能存”的业务级反馈方式。别指望它返回字节数,只能回答“现在存 2MB 应该没问题”或“10MB 已经失败”。
真正棘手的地方在于:浏览器从不承诺“剩余配额”这个概念。所谓“剩余”,只是当前策略下的一次性估算,下次写入时可能因后台清理、系统策略变更或跨 origin 存储竞争而完全不同。别把它当硬盘剩余空间看待。











