appcache已废弃,因其设计缺陷(如缓存更新滞后、白屏风险)被现代浏览器彻底移除;必须迁移到service worker+cache api,通过缓存命名版本化、install/activate阶段控制、显式清理旧缓存实现可靠离线更新。

manifest 文件不更新,资源永远不会变
AppCache 的版本管理完全依赖 demo.appcache 文件内容是否变化——哪怕只多一个空格,浏览器就会触发重新下载全部缓存资源。但反过来,如果只更新了 js/main.js 却没动 demo.appcache,浏览器根本不会拉新 JS,用户永远卡在旧版本。
常见错误现象:applicationCache.status 一直是 1(IDLE),checking 事件不触发;开发者改完代码发现离线页面还是老的,排查半天才发现 manifest 没改。
- 必须用注释行做版本标记,比如
# v2.1.0或# 20260618,不能靠时间戳自动生成(服务端缓存可能拦截) - 服务器必须对
.appcache文件禁用缓存:Cache-Control: no-cache, no-store, must-revalidate - Apache/Nginx 需显式配置 MIME 类型为
text/cache-manifest,否则浏览器直接忽略该文件
Service Worker 的缓存命名才是真正的版本控制
和 AppCache 不同,Service Worker 把缓存控制权交还给开发者。它不靠文件内容哈希自动更新,而是靠你主动命名缓存空间(如 'v2-cache'),并在 install 阶段清旧存新。
使用场景:上线新版本时,只需改缓存名、更新 sw.js 内容,浏览器检测到脚本变更就会安装新 worker,旧缓存自然废弃。
- 不要复用同一个缓存名,比如始终用
cacheName='static-v1',否则无法清理旧资源 -
self.skipWaiting()和clients.claim()必须配对使用,否则新缓存只对下次访问生效 - 差量更新不存在于 Service Worker 层面——它是全量替换缓存空间,但你可以按需只
cache.addAll()变更过的资源路径
Cache API 中的资源路径匹配很脆弱
Service Worker 拦截请求后,用 cache.match(request) 查找缓存,但匹配是严格基于 URL 字符串的。带查询参数的请求(如 /api/data.json?t=123)和无参版本被视为不同资源,容易造成缓存冗余或未命中。
使用 Puppeteer + Chrome 将 HTML 渲染为中文 PDF,自动处理图表等待、Tab 展开、动画、测高、白边消除、防分页,适用于看板、报表、网页和交互图表转 PDF。
容易踩的坑:fetch 事件里直接 event.respondWith(cache.match(event.request)),结果动态接口没缓存、静态资源却因 URL 参数不一致反复重下。
- 对需要缓存的资源,统一剥离查询参数再匹配,例如用
new Request(new URL(event.request.url).origin + event.request.url.pathname) - 对带版本号的静态资源(如
style.css?v=3.2.1),建议构建时去掉?v=xxx,改用文件名哈希(style.a1b2c3.css)更可靠 - 避免在
cache.put()时传入带时间戳的 Request 实例,否则缓存键不可控
离线状态下 fallback 页面的加载时机很关键
AppCache 的 FALLBACK 是声明式降级,而 Service Worker 是命令式拦截。如果你在 fetch 事件中写 if (!navigator.onLine) { return caches.match('/offline.html') },看似合理,但实际会失败——因为 /offline.html 本身也得提前缓存好,否则离线时连 fallback 都打不开。
真实问题:用户首次访问就断网,Service Worker 还没 install 完,/offline.html 根本不在 cache 里。
- 所有 fallback 资源(HTML/CSS/JS/图片)必须包含在
install阶段的cache.addAll()列表中 - 不要依赖
navigator.onLine做判断——它只是指示浏览器是否认为联网,不是真实网络状态;应以fetch()抛错为依据 - fallback 页面最好内联关键 CSS,避免它自己又触发额外请求而失败
AppCache 已死,Service Worker 的版本管理本质是“缓存空间生命周期管理”,而不是文件级 diff。真正难的不是怎么存,是怎么让新旧缓存平滑交接、让用户感知不到切换过程——这要求你对 install、activate、fetch 三个阶段的执行顺序和 side effect 有精确把握。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










