navigator.storage.persist() 仅承诺尽力持久化,实际仍可能被清理,因取决于用户活跃度、存储总量及浏览器策略;需先检查权限、定期保活并监控配额。
navigator.storage.persist 申请后仍被清理?调用 navigator.storage.persist() 成功返回 true 并不保证数据永不丢失。浏览器只承诺「尽力持久化」,实际是否豁免清理,取决于用户行为、存储总量、站点活跃度及浏览器策略(如 Chrome 会定期检查「站点参与度」)。若用户长时间未访问、或该源总存储接近上限,即使已申请持久化,Cache API 或 IndexedDB 仍可能被静默清空。
persist()
直接调用 navigator.storage.persist() 可能因权限未获准而静默失败(尤其在非安全上下文或 iframe 中)。务必先用 navigator.permissions.query() 确认状态:
if ('permissions' in navigator) { const result = await navigator.permissions.query({ name: 'persistent-storage' }); if (result.state === 'granted') { const persisted = await navigator.storage.persist(); console.log('持久化已启用:', persisted); // true 表示当前已持久化 } else if (result.state === 'prompt') { // 用户尚未决定,调用 persist() 会触发弹窗 const persisted = await navigator.storage.persist(); }}
result.state 可能为 'granted'、'denied' 或 'prompt',不能只依赖 persist() 返回值判断是否生效iframe 中调用需确保其 sandbox 属性包含 allow-scripts,且父页面允许跨域访问存储navigator.storage 本身为 undefined
Chrome 和 Edge 会基于「最近使用时间」和「交互频率」动态调整持久化资格。即使已申请成功,若站点连续 7 天无用户交互(如点击、键盘输入、fetch 请求),可能被降级为临时存储。
IndexedDB 写入一个时间戳记录)可维持活跃标识Service Worker 后台定时任务——无前台页面时,这些任务可能被节流或跳过,无法有效「保活」visibilitychange 事件中检测用户回归,并立即执行一次小体积 cache.match() 或 IDBKeyRange.bound() 查询,有助于刷新活跃度信号navigator.storage.persist() 不扩大配额上限,只是改变清理优先级。实际可用空间仍由 navigator.storage.estimate() 报告,且不同浏览器差异明显:
const { usage, quota } = await navigator.storage.estimate();console.log(`已用 ${usage} / 总配额 ${quota}`); // quota 在 Chrome 中常为 0(表示「尽力而为」),Firefox 则可能返回具体字节数
QuotaExceededError
quota > usage 就安全——quota 值可能滞后于实际可用空间,尤其在磁盘紧张时真正关键的不是「有没有点那个按钮」,而是持续监控 storage.estimate()、响应 storage 事件,并在接近阈值时主动清理冷数据——浏览器不会替你做这个决策。