caches.delete() 不会自动识别过期缓存,因 cache storage 无内置 ttl;需手动通过时间戳、响应头或缓存名约定判断并清理。

为什么 caches.delete() 不会自动识别“过期”缓存
浏览器的 Cache Storage 没有内置的 TTL(生存时间)或自动过期机制。caches.delete() 只是无条件删除指定名称的缓存空间,它根本不知道什么叫“过期”。所谓“过期”,必须由你定义并判断——比如缓存创建超过 24 小时、或某个响应头里 Cache-Control: max-age=3600 已失效、或你手动在缓存中存了时间戳。
如何用时间戳标记并筛选过期缓存
推荐在写入缓存时,把时间戳作为元数据存进缓存条目(例如在 Response 的 headers 中加自定义字段,或单独缓存一个 __metadata 键)。但更简单直接的做法是:在调用 caches.keys() 获取所有缓存名后,对每个缓存执行 caches.open(),再读取其中某条响应的 date 或自定义 header 判断是否过期。
- 不建议遍历整个缓存读所有请求——开销大,且 Service Worker 环境下可能被中断
- 更轻量的做法:只检查缓存中第一个可用响应(如
/index.html或/manifest.json)的时间信息 - 如果缓存中没存时间信息,就只能靠缓存名约定,例如命名成
v1-20240520,然后用正则提取日期再比对
caches.delete() 删除前必须注意的异步时机
这个方法返回 Promise,但很多人误以为它“立刻生效”。实际上,如果该缓存正被 fetch 事件或其他 API 使用(比如另一个 fetch 正在从它读取),caches.delete() 会等待那些操作完成才真正删除。这意味着:
- 不能在
self.addEventListener('fetch', ...)中同步调用caches.delete()并期望下个请求就用不到它——中间可能有竞态 - 若想确保删除后新请求走网络,应在
install或activate阶段做清理,并在activate的waitUntil()中 awaitcaches.delete() - 删除失败时不会抛错,要显式检查返回值:
const deleted = await caches.delete('old-cache');——deleted是布尔值
一个可直接复用的清理函数示例
下面这段代码在 Service Worker 的 activate 事件中运行,删除所有名称匹配 ^myapp-v\d+-\d{8}$ 且日期早于 7 天前的缓存:
self.addEventListener('activate', event => {
const cutoff = Date.now() - 7 * 24 * 60 * 60 * 1000;
event.waitUntil(
caches.keys().then(keys => {
return Promise.all(
keys
.filter(key => /^myapp-v\d+-\d{8}$/.test(key))
.map(key => {
const dateStr = key.match(/-(\d{8})$/)[1];
const cacheDate = new Date(`${dateStr.slice(0,4)}-${dateStr.slice(4,6)}-${dateStr.slice(6,8)}`);
return cacheDate.getTime() <p>注意:正则中的 <code>\d{8}</code> 假设你按 <code>YYYYMMDD</code> 格式命名缓存;如果用的是时间戳或语义化版本(如 <code>v2.1.0</code>),就得换判断逻辑。</p><p>真正的难点不在删除动作本身,而在于你怎么定义和维护“过期”这个状态——它必须是你主动写进去、也必须由你主动读出来。没有魔法,只有约定和执行。</p>前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











