PWA (Progressive Web App) 是一种结合网页和原生应用优点的应用技术。
| 特性 | 说明 |
|---|---|
| 📥 可安装 | 添加到主屏幕,像原生应用一样启动 |
| ⚡ 快速 | Service Worker 缓存,秒开应用 |
| 🔄 离线 | 基础功能可离线访问 |
| 🔄 自动更新 | 无需应用商店,自动更新 |
| 💾 小体积 | 无需下载大型安装包 |
在 Android 平台,Chrome 和 Edge 会生成真正的 WebAPK:
- ✅ 出现在应用抽屉中
- ✅ 可在系统设置中管理
- ✅ 完整的全屏体验
- ✅ 与原生应用无异
- 应用名称、图标、主题色
- 独立显示模式(无浏览器UI)
- 快捷方式(快速添加密钥、扫描二维码)
- 协议处理器(otpauth:// 链接)
- 静态资源缓存: HTML、CSS、JS
- CDN 资源缓存: jsQR、qrcode-generator
- 智能缓存策略: Cache First 优先
- 自动更新: 检测新版本并自动应用
- 清理旧缓存: 保持存储空间整洁
- 📴 离线数据修改: 支持离线添加、修改、删除密钥(v2.1 新功能)
- 🔄 后台同步: 网络恢复时自动同步离线操作(Background Sync API)
- 📱 智能安装提示: 自动显示漂亮的安装横幅,引导用户安装应用
- 📡 离线状态指示器: 实时显示在线/离线状态,离线时显示醒目的状态标识
- 🔄 状态同步反馈: 离线操作和同步状态实时反馈给用户
- iOS Safari 完整支持
- Android Chrome/Edge 完整支持
- Windows 桌面支持
- macOS 支持
- ✅ 查看已加载的密钥列表
- ✅ 生成 OTP 验证码(本地计算,无需网络)
- ✅ 添加新密钥(离线时保存,网络恢复后自动同步)
- ✅ 修改现有密钥(离线时保存,网络恢复后自动同步)
- ✅ 删除密钥(离线时保存,网络恢复后自动同步)
- ✅ 批量导入(离线时保存,网络恢复后自动同步)
-
离线时的操作
用户操作 → Service Worker 拦截 ↓ 保存到 IndexedDB 离线队列 ↓ 返回"操作已保存"提示(202 状态码) ↓ 显示"您处于离线状态,操作已保存,网络恢复后将自动同步" -
网络恢复时的同步
网络连接恢复 → 触发 Background Sync ↓ Service Worker 按时间顺序同步所有操作 ↓ 成功:删除队列中的操作,刷新页面数据 失败:重试(最多 5 次),超过后标记为失败 ↓ 显示同步结果:"已同步 X 个离线操作"
| 组件 | 说明 |
|---|---|
| IndexedDB | 存储待同步的离线操作 |
| Background Sync API | 网络恢复时自动触发同步 |
| Service Worker | 拦截 API 请求,管理离线队列 |
| 重试机制 | 失败操作最多重试 5 次 |
| 冲突检测 | 按时间戳顺序同步,避免数据冲突 |
- 离线时无法获取最新的服务器数据(密钥列表不会更新)
- 如果多设备同时离线修改同一密钥,后同步的操作会覆盖先同步的
- 建议单设备使用,或避免在离线时修改相同的密钥
✅ 数据安全:
- 离线操作存储在浏览器 IndexedDB 中,不会丢失
- 即使关闭浏览器,待同步操作仍然保留
- 网络恢复后会自动同步,无需手动操作
| 浏览器 | Background Sync | IndexedDB | 离线功能 |
|---|---|---|---|
| Chrome 49+ | ✅ | ✅ | ✅ 完整支持 |
| Edge 79+ | ✅ | ✅ | ✅ 完整支持 |
| Firefox 117+ | ✅ | ||
| Safari 14+ | ❌ 不支持 | ✅ |
说明:
- ✅ 完整支持:网络恢复时自动同步
⚠️ 部分支持:需要手动刷新页面触发同步- ❌ 不支持:离线操作会保存,但需手动刷新
-
访问应用
https://2fa-dev.guts.eu.org/ -
安装方式:
方式 1: 自动提示(推荐)✨
- 页面底部会自动弹出精美的「安装到桌面」横幅(v2.2 新功能)
- 横幅会在首次访问后短暂延迟显示
- 点击横幅上的「安装」按钮即可
- 如果不想安装,点击「×」关闭横幅
方式 2: 浏览器原生提示
- 浏览器地址栏可能会显示安装图标
- 点击「添加」或「安装」
方式 3: 手动安装
- 点击浏览器菜单(右上角 ⋮)
- 选择「添加到主屏幕」或「安装应用」
- 点击「安装」
-
验证安装
- 应用图标出现在桌面和应用抽屉
- 从应用抽屉打开,享受全屏体验
- 在系统设置 → 应用中可以找到「2FA」
特别说明: Chrome 和 Edge 会生成真正的 WebAPK,提供完整的原生应用体验。
-
访问应用
https://2fa-dev.guts.eu.org/ -
安装步骤:
- 点击顶部工具栏的 分享按钮 (↑)
- 向下滚动,找到「添加到主屏幕」
- 点击「添加」
- 自定义应用名称(可选)
-
启动应用
- 从主屏幕点击图标启动
- 应用以全屏模式运行
注意: iOS 的 PWA 支持有限:
- ✅ 基础离线功能可用
- ❌ 后台同步受限
-
访问应用
https://2fa-dev.guts.eu.org/ -
安装方式:
方式 1: 地址栏安装图标
- 地址栏右侧会出现 安装图标 (⊕ 或 💻)
- 点击图标
- 点击「安装」
方式 2: 菜单安装
- 点击浏览器菜单(右上角 ⋮)
- 选择「安装 2FA ...」
- 点击「安装」
-
验证安装
- 应用图标出现在桌面
- 应用出现在开始菜单(Windows)或应用程序文件夹(macOS)
- 可以独立窗口运行,无浏览器UI
2FA 使用智能分层缓存策略:
┌─────────────────────────────────────────┐
│ 静态资源 (Cache First) │
│ - / (主页面) │
│ - /manifest.json │
│ - /icon-192.png, /icon-512.png │
│ 缓存优先,更新时替换 │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ CDN 资源 (Cache First + CORS) │
│ - jsQR.min.js (二维码识别) │
│ - qrcode.min.js (二维码生成) │
│ 缓存优先,失败时从网络获取 │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ API 请求 (Network Only) │
│ - /api/secrets │
│ - /api/backup │
│ 始终从网络获取最新数据,不缓存 │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────┐
│ 外部资源 (Network Only + Pass Through) │
│ - favicon, logo 等 │
│ 直接透传,失败时静默处理 │
└─────────────────────────────────────────┘
Service Worker 会自动检测并应用新版本:
- 新版本发布后,后台自动下载和安装
- 下次访问或刷新页面时自动使用新版本
- 无需用户手动操作,完全透明
离线状态指示器:实时显示网络状态:
- 📡 当网络断开时,页面右上角会显示"离线模式"指示器
- 🌐 网络恢复时,指示器自动消失,并显示"正在同步..."提示
- 离线期间的操作会自动保存到本地队列
- 网络恢复后自动同步所有离线操作
// Service Worker 生命周期
1. 安装 (Install)
↓
预缓存静态资源和 CDN 库
↓
skipWaiting() - 立即激活
2. 激活 (Activate)
↓
清理旧版本缓存
↓
clients.claim() - 立即控制页面
3. 拦截请求 (Fetch)
↓
根据资源类型应用不同缓存策略
↓
返回缓存或网络响应
4. 更新检查 (每小时)
↓
检测新版本 Service Worker
↓
自动更新并通知用户当前版本: v2
版本历史:
v2(2025-10-24): 优化 CDN 缓存策略,修复 CORS 错误v1(2025-10-23): 初始版本,基础缓存功能
查看 Service Worker 状态:
-
Chrome DevTools:
- F12 → Application → Service Workers
- 查看注册状态和缓存内容
-
chrome://serviceworker-internals/:
- 查看所有已注册的 Service Worker
- 可以手动卸载或更新
原因:
- Service Worker 未成功注册
- 未满足 PWA 安装条件
- 浏览器不支持 PWA
解决方案:
-
检查 HTTPS:
确保使用 HTTPS 访问(Cloudflare Workers 自动提供) -
检查 Service Worker:
- Chrome:
chrome://serviceworker-internals/ - 查找
2fa-dev.guts.eu.org - 确认状态为「ACTIVATED and is running」
- Chrome:
-
清除缓存并重新访问:
Chrome → 设置 → 隐私和安全 → 清除浏览数据 选择「缓存的图片和文件」→ 清除 -
等待足够时间:
- 访问网站至少 30 秒
- 让 Service Worker 完成注册
检查方法:
- 打开浏览器控制台(F12)
- 查看是否有错误信息
- 检查 Application → Service Workers
常见错误:
错误 1: Failed to register service worker
原因: Service Worker 文件无法访问
解决: 确认 /sw.js 可以正常访问
错误 2: DOMException: Only secure origins are allowed
原因: 未使用 HTTPS
解决: 使用 HTTPS 访问(Cloudflare Workers 自动提供)
检查清单:
- ✅ Service Worker 已注册并激活
- ✅ 至少访问过一次在线版本(预缓存资源)
- ✅ 尝试访问的功能已被缓存
已缓存的功能:
- ✅ 主页面UI
- ✅ 查看已保存的密钥
- ✅ 生成 OTP(基于本地时间)
- ✅ 二维码生成(CDN 库已缓存)
需要网络的功能:
- ❌ 添加/编辑/删除密钥(需要 API)
- ❌ 备份和恢复(需要 API)
- ❌ 登录认证(需要 API)
手动触发更新:
-
浏览器刷新:
- 按
Ctrl+Shift+R(Windows/Linux) - 按
Cmd+Shift+R(macOS)
- 按
-
卸载并重新安装:
- Android: 设置 → 应用 → 2FA → 卸载
- iOS: 长按图标 → 删除
- 桌面: 右键图标 → 卸载
- 重新访问网站并安装
-
清除 Service Worker:
chrome://serviceworker-internals/ 找到 2fa-dev.guts.eu.org 点击「Unregister」 刷新页面重新注册
现象:
- 二维码扫描功能不可用
- 二维码生成功能不可用
- 控制台显示 CDN 资源加载错误
解决方案:
-
检查网络连接:
- 确保可以访问外部 CDN
-
清除缓存:
Chrome → F12 → Application → Storage → Clear site data -
检查 Service Worker 缓存:
Chrome → F12 → Application → Cache Storage 查看 2fa-v2 缓存 确认 jsQR.min.js 和 qrcode.min.js 已缓存
-
定期访问在线版本:
- 确保获得最新功能和安全更新
- 更新缓存资源
-
及时同步数据:
- PWA 支持离线查看,但数据变更需要网络
-
保持应用更新:
- 当看到更新提示时,及时刷新应用
-
首次加载:
- 约 1-2 秒(全球平均,Cloudflare CDN)
-
后续加载:
- < 500ms(从缓存加载)
-
离线启动:
- < 300ms(完全离线)
| API | 支持状态 |
|---|---|
| Cache API | ✅ 完全支持 |
| Fetch API | ✅ 完全支持 |
| Background Sync | 🚧 预留接口 |
| Push Notifications | 🚧 计划中 |
| Periodic Background Sync | 🚧 计划中 |
| 浏览器 | 版本要求 | PWA 支持 | WebAPK |
|---|---|---|---|
| Chrome | ≥ 90 | ✅ | ✅ (Android) |
| Edge | ≥ 90 | ✅ | ✅ (Android) |
| Safari | ≥ 14 | 🟡 部分 | ❌ |
| Firefox | ≥ 88 | 🟡 部分 | ❌ |
| Opera | ≥ 76 | ✅ | ✅ (Android) |
图例:
- ✅ 完全支持
- 🟡 部分支持
- ❌ 不支持
-
后台同步:
- 离线时的操作队列
- 恢复网络后自动同步
-
周期性后台同步:
- 定期检查更新
- 自动备份
-
离线编辑:
- 完整的离线 CRUD 操作
- 自动冲突解决
Service Worker 版本: v1 (自动化版本管理)
v2.2 更新内容:
- ✨ 新增智能安装提示横幅
- ✨ 新增离线状态指示器,实时显示网络状态
- 📱 优化 PWA 用户体验
- 🔄 简化更新流程,自动应用新版本