pwa离线缓存的真正入口是service worker文件(如sw.js)和manifest.json,而非index.html;index.html仅负责注册service worker,缓存逻辑由sw.js中install事件的cache.addall()和fetch事件的响应策略决定,manifest.json的start_url仅指定启动页路径,不参与缓存控制。

什么是PWA离线缓存的真正入口
PWA离线缓存没有“HTML代码配置入口”这个说法——index.html本身不是缓存控制点,它只是被缓存的资源之一。真正起作用的是 service worker 文件(通常叫 sw.js)和 manifest.json,而 HTML 只负责注册它们。
常见错误是直接在 index.html 里写一堆缓存逻辑,结果发现离线打不开页面。根本原因:浏览器只按 service worker 的 fetch 事件和 cache.addAll() 等逻辑执行缓存,HTML 不参与决策。
-
index.html必须通过navigator.serviceWorker.register('sw.js')启动 worker -
sw.js必须用self.skipWaiting()和clients.claim()避免旧版本残留 -
manifest.json的start_url和scope决定 PWA 启动时加载哪个 HTML,但它不控制缓存内容
如何让 index.html 成为可离线访问的“入口页”
关键不是“配置HTML”,而是确保 HTML 被 service worker 显式缓存,并且能响应离线 fetch 请求。
- 在
sw.js的install事件中,把index.html加入缓存列表:cache.addAll(['/', '/index.html', '/styles.css']) - 在
fetch事件中,对根路径/或/index.html的请求,必须从 cache 中返回,不能 fallback 到 network(否则离线时失败) - 注意路径匹配:如果
scope是/app/,那index.html实际路径是/app/index.html,缓存和 fetch 匹配都要带前缀 - 开发时用 Chrome DevTools 的 Application → Service Workers → “Update on reload” + “Offline” 模拟验证,别只靠刷新判断
为什么 manifest.json 的 start_url 不等于缓存入口
start_url 只影响用户点击桌面图标或从主屏启动时浏览器加载的初始 URL,它不触发缓存、也不决定哪些文件被存。很多人误以为设了 "start_url": "/offline.html" 就能自动缓存那个文件——其实不会,除非你在 sw.js 里明确 cache.add('/offline.html')。
-
start_url必须与scope同域且可被 service worker 控制(比如scope: "/"时,start_url: "/"才有效) - 如果
start_url指向一个未被缓存的路径(如/dynamic-page),离线启动会白屏或报错net::ERR_FAILED -
display: "standalone"或"minimal-ui"不影响缓存行为,只改 UI 表现
常见离线失败的三个硬坑
-
sw.js 注册失败:检查路径是否 404、MIME 类型是否为 application/javascript(Nginx/Apache 需显式配置)、是否在 HTTPS 下运行(localhost 除外)
- 缓存策略写错:用
cache.match(event.request) 但没处理 undefined 返回值,导致离线时返回空响应而不是 fallback 页面
- HTML 自身引用了未缓存的资源:比如
index.html 里写了 <script src="@#@#@#@#@#@#@#@#@#@0;%EF%BC%8C%E8%BF%99%E4%B8%AA%E5%A4%96%E9%93%BE%20JS%20%E4%B8%8D%E5%9C%A8%E7%BC%93%E5%AD%98%E4%B8%AD%EF%BC%8C%E7%A6%BB%E7%BA%BF%E6%97%B6%E6%95%B4%E4%B8%AA%E9%A1%B5%E9%9D%A2%20JS%20%E5%A4%B1%E6%95%88%20%20
sw.js 注册失败:检查路径是否 404、MIME 类型是否为 application/javascript(Nginx/Apache 需显式配置)、是否在 HTTPS 下运行(localhost 除外) cache.match(event.request) 但没处理 undefined 返回值,导致离线时返回空响应而不是 fallback 页面 index.html 里写了 <script src="@#@#@#@#@#@#@#@#@#@0;%EF%BC%8C%E8%BF%99%E4%B8%AA%E5%A4%96%E9%93%BE%20JS%20%E4%B8%8D%E5%9C%A8%E7%BC%93%E5%AD%98%E4%B8%AD%EF%BC%8C%E7%A6%BB%E7%BA%BF%E6%97%B6%E6%95%B4%E4%B8%AA%E9%A1%B5%E9%9D%A2%20JS%20%E5%A4%B1%E6%95%88%20%20service%20worker%20%E7%9A%84%E7%BC%93%E5%AD%98%E9%80%BB%E8%BE%91%E6%98%AF%E5%94%AF%E4%B8%80%E5%8F%AF%E4%BF%A1%E5%85%A5%E5%8F%A3%EF%BC%8CHTML%20%E5%8F%AA%E6%98%AF%E8%BD%BD%E4%BD%93%E3%80%82%E6%BC%8F%E6%8E%89%20cache.addAll%20%E9%87%8C%E7%9A%84%E6%9F%90%E4%B8%AA%20CSS%20%E6%88%96%E5%AD%97%E4%BD%93%E6%96%87%E4%BB%B6%EF%BC%8C%E5%B0%B1%E5%8F%AF%E8%83%BD%E8%AE%A9%E7%A6%BB%E7%BA%BF%E9%A1%B5%E9%9D%A2%E6%A0%B7%E5%BC%8F%E5%B4%A9%E5%A1%8C%E2%80%94%E2%80%94%E8%BF%99%E7%A7%8D%E7%BB%86%E8%8A%82%E6%AF%94%E2%80%9C%E6%80%8E%E4%B9%88%E5%86%99%20manifest%E2%80%9D%E6%9B%B4%E5%86%B3%E5%AE%9A%E6%88%90%E8%B4%A5%E3%80%82
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











