html本身不是pwa,真正使其成为pwa的只有manifest.json、service worker和https(localhost除外);manifest.json必须包含name、short_name、start_url、display及至少含192x192和512x512 png图标的icons字段,缺一或格式错误即导致pwa激活失败。

直接说结论:HTML 本身不是 PWA,但它是唯一入口;真正让网页变成 PWA 的,只有三样东西——manifest.json、Service Worker 和 HTTPS(localhost 是唯一例外)。缺一不可,漏一个,“添加到桌面”按钮就永远不会出现。
manifest.json 必须填哪些字段才被浏览器认作 PWA
浏览器只校验几个硬性字段,写错或缺失任意一个,manifest.json 就算加载成功,PWA 也不会激活,更不会显示安装提示。
-
name和short_name都必须存在:short_name用于桌面图标文字,Chrome 要求 ≤12 字符(含空格),超长或含不可见 Unicode 会导致解析失败 -
start_url必须是相对路径(如"/"或"/index.html"),且该 URL 必须返回 HTTP 200 —— 重定向到登录页(302)或返回 404 都会直接判失败 -
display推荐设为"standalone";设成"browser"就退化为普通标签页,不算 PWA -
icons至少提供两个 PNG:尺寸严格写成"192x192"和"512x512",src必须是可被fetch()访问的路径(如"/icons/icon-192.png"),404 会导致整个 manifest 加载失败
常见错误:manifest.json 放在 /static/manifest.json 却没在 <link> 中显式指定 href,浏览器默认请求 /manifest.json → 404 → 静默放弃;Nginx/Apache 还需确保响应头含 Content-Type: application/manifest+json。
Service Worker 注册不生效的典型原因
注册失败几乎从不报错,控制台静默跳过——这是最常卡住人的地方。问题基本不出在 JS 语法,而在于环境或路径。
- 必须跑在 HTTPS 下(
localhost可以,但http://127.0.0.1不行) -
navigator.serviceWorker.register()的参数是相对于当前页面 URL 的,不是 JS 文件位置。比如页面在/blog/post.html,要注册根目录的sw.js,得写navigator.serviceWorker.register("/sw.js"),不能写"./sw.js" - 注册后刷新页面看不到效果:Service Worker 默认要等下次页面加载才激活。开发时可用
skipWaiting()+clients.claim()强制接管,但上线前务必删掉 - 验证是否生效:打开 DevTools → Application → Service Workers,状态必须是
"Activated and is running",并勾选"Update on reload"
离线缓存为什么加了 Service Worker 还不工作
很多人以为在 install 事件里调用 caches.addAll() 就万事大吉,其实这只是缓存静态资源的第一步;fetch 事件没处理,用户依然无法离线访问。
-
fetch事件里必须显式调用caches.match()并return response || fetch(request),否则请求直接走网络,缓存形同虚设 -
cache.addAll()只缓存 install 阶段列出的资源;JS/CSS 等静态资源适合缓存,但 Service Worker 更新时旧缓存不会自动清理——得在activate事件里遍历caches.keys()手动删旧版本 - API 请求别盲目缓存:带用户态的接口(如
/api/user/profile)缓存前必须把 auth token 或用户 ID 加进 cache key,否则不同用户看到同一缓存 -
fetch()默认不带 cookie,需要显式传{ credentials: "include" },否则登录态请求会 401
Lighthouse 检测不通过的三个硬伤点
Lighthouse 的 PWA 分数低,往往不是功能没做全,而是卡在几个具体可验证的细节上,改完立刻见效。
-
start_url返回非 200(比如重定向到 login 页面)→ 直接判失败。确保该 URL 可以无条件返回 HTML -
manifest.json缺display或start_url→ 浏览器连“添加到桌面”按钮都不渲染 - Service Worker 没处理
fetch事件,或没返回有效 response → Lighthouse 判定“离线不可用”
最易被忽略的是:iOS Safari 完全忽略 manifest.json 中的 icons,只认 <link rel="apple-touch-icon">;Android Chrome 则严格依赖 192x192 和 512x512。两者必须分开适配,不能指望一份配置通吃。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











