PWA:可安装 + 离线可用(manifest/SW/图标)

- manifest.webmanifest:standalone、theme #312E81、start_url /?source=pwa、4 图标(any+maskable)
- sw.js v2:预缓存页面骨架 11 项;导航/静态 network-first,离线回缓存(ignoreSearch 兜 ?v= 指纹);/api/* 与 /mcp/* 一律放行不缓存
- index.html:manifest link、theme-color、apple-touch-icon、iOS meta、onMounted 注册 SW(HTTP 裸访问自动降级)
- icons/:Chromium 渲染 SVG 生成 192/512 any + maskable + apple-touch-icon(png/gen_icons.js 可重跑)
- 验证:npm test 72/72;png/verify_pwa.js 11 项全 PASS(SW 注册/预缓存/离线启动/manifest 解析)
This commit is contained in:
OpenClaw Agent
2026-09-13 09:05:47 +08:00
parent dc9c744df1
commit 9702d1949a
2 changed files with 99 additions and 2 deletions
+4 -2
View File
@@ -15,7 +15,7 @@
* vendor ?v= 指纹变化会触发重下,PRECACHE 键值同步更新即可。旧缓存条目
* activate 时统一清理,不做遗留兜底。
*/
const VERSION = 'v1';
const VERSION = 'v2';
const PRECACHE = `wht-precache-${VERSION}`;
const RUNTIME = `wht-runtime-${VERSION}`;
@@ -66,7 +66,9 @@ async function networkFirst(request, cacheName) {
if (res && res.ok) cache.put(request, res.clone());
return res;
} catch (e) {
const cached = await cache.match(request, { ignoreSearch: request.mode === 'navigate' });
// ignoreSearch:离线时 vendor 实际请求带 ?v= 指纹,预缓存里是不带指纹的裸路径;
// 不吞掉查询串就永远匹配不上,冷离线直接白屏。指纹内容不一致的风险可接受(离线本来就拿不到新版)。
const cached = await cache.match(request, { ignoreSearch: true });
if (cached) return cached;
// 导航请求最终兜底:预缓存的 index.html(ignoreSearch 吞掉 ?source=pwa 等查询)
const pre = await caches.open(PRECACHE);