html离线唯一可行方案是service worker:须https/localhost下注册,install阶段用cache.addall()预缓存html及其全部依赖资源(路径须为绝对根路径),fetch事件中按request.destination精准分流请求,activate阶段清理旧缓存。

HTML 本身不能创建离线应用缓存——所有现代浏览器已彻底废弃 manifest.json 和 ,仅靠 HTML 标签或 meta 配置无法实现可靠离线。真正可行的路径只有一条:用 ServiceWorker 拦截请求并管理 CacheStorage。
怎么注册 Service Worker 才不静默失败
注册失败往往没报错,但控制台里会显示 Failed to register a ServiceWorker 或根本无反应。核心限制就三条:
- 必须在
https://或http://localhost下运行;file://、http://192.168.x.x、http://example.com(没 HTTPS)全部不支持 -
navigator.serviceWorker.register()必须在window.addEventListener('load', ...)里调用,不能写在<script></script>标签顶部或异步模块中 -
sw.js文件必须能被直接访问:打开https://yoursite.com/sw.js应返回 JS 内容,不能是 404、重定向、或 Nginx 返回Cache-Control: no-store
install 阶段缓存资源为什么总不生效
cache.addAll() 看似简单,实际极易中断失败。常见原因:
- 列表中任意一个 URL 返回非 2xx 响应(比如
/app.js404、CORS 被拒、字体跨域 MIME 不匹配),整个缓存操作就终止,一个资源都不会写入 - 路径必须是绝对根路径:
'/index.html'✅,'./index.html'❌,'index.html'❌,'/static/app.js?v=2.1'❌(带查询参数会被视为不同键,浪费空间且易失效) - HTML 文件不能单独缓存——它引用的
<script src="app.js"></script>、<link href="style.css">、<img src="logo.png">必须全部列进urlsToCache
fetch 事件里怎么避免白屏又不乱缓存 API
单行 event.respondWith(caches.match(event.request)) 是最危险的写法:它会把 POST 请求、带 credentials: 'include' 的登录接口也去匹配缓存,导致表单静默失败或登录态丢失。
将调研报告、方案对比、数据分析、需求梳理、会议纪要、设计说明、代码评审、学习笔记等任务产物输出为可在浏览器直接打开的单文件 HTML,替代 Markdown 作为最终交付物。Markdown 在信息密度、视觉清晰度和可分享性上已跟不上 AI 产物的丰富度,HTML 能同时承载排版、表格、SVG 等。
必须按 request.destination 精准分流:
-
event.request.destination === 'document':主页面请求,必须命中缓存,否则离线白屏;建议 fallback 到预存的offline.html字符串 -
=== 'script'或=== 'style':可直接caches.match()返回,静态资源缓存优先没问题 -
=== 'json'或空字符串(如fetch('/api/user')):适合stale-while-revalidate,先返回缓存,再 fetch 更新;注意响应头要设Cache-Control: max-age=0, stale-while-revalidate=60 -
=== 'image'或=== 'font':加try/catch,fetch 失败时跳过缓存,避免阻塞渲染
旧缓存怎么清理才不崩掉正在用的页面
HTML 文件更新了,用户还是看到旧版?不是缓存没更新,而是旧缓存还躺在 CacheStorage 里没删。清理必须满足两个条件:
- 动作只能放在
activate事件里,绝不能在install阶段删——此时旧 SW 还在运行,删了会导致页面请求失败 - 必须避开当前正在使用的缓存名:给每个版本起带语义的名字,比如
'pages-v2.3.1'、'assets-20260513',activate中只删不含当前版本号的缓存 - 配合
self.clients.claim()确保新 SW 尽快接管,减少多版本共存窗口期
最容易被忽略的是:HTTP 缓存头(如 Cache-Control)和 CacheStorage 完全无关。就算你把服务器响应头设成 no-cache,已存进 caches.open('v1') 的资源依然存在,必须靠 activate 里的 caches.delete() 显式清除。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










