Service Worker 和 IndexedDB 是 PWA 离线能力的两大核心:SW 拦截请求并缓存静态资源,IndexedDB 存储结构化动态数据;二者协同实现离线加载、渲染与交互。

Service Worker 和 IndexedDB 是 PWA 实现可靠离线能力的两大核心支柱:前者拦截网络请求并控制缓存策略,后者提供结构化、可查询的本地数据存储。二者配合,能让应用在无网络时仍加载页面、展示内容、甚至支持用户交互与数据写入。
注册并激活 Service Worker
Service Worker 必须通过 HTTPS(或 localhost)注册,且作用域需明确。通常在主页面 JS 中注册:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js')
.then(reg => console.log('SW registered:', reg.scope))
.catch(err => console.error('SW registration failed:', err));
});
}
注意:sw.js 必须放在站点根目录或其子路径下,否则作用域受限;首次注册后需刷新两次才能完全生效(第一次安装,第二次激活)。
用 Cache API 缓存静态资源
在 Service Worker 的 install 阶段预缓存 HTML、CSS、JS、图标等关键静态文件:
立即学习“前端免费学习笔记(深入)”;
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 使用
cache.addAll()批量存入,确保离线时可直接读取 - 为每个缓存版本命名(如
'v1-static'),便于后续更新与清理 - 在 fetch 事件中优先匹配缓存,未命中再走网络,并将响应存入缓存(可选)
示例逻辑片段:
self.addEventListener('fetch', e => {
e.respondWith(
caches.match(e.request).then(res => res || fetch(e.request))
);
});
用 IndexedDB 存储动态内容
Cache API 不适合存储大量结构化数据(如文章列表、用户表单、聊天记录)。IndexedDB 提供异步、事务性、键值+索引查询能力:
- 在 Service Worker 或页面主线程中打开数据库(推荐在页面中初始化,避免 SW 中阻塞)
- 设计 object store(类似表),添加 keyPath 和 index(如按
timestamp或status查询) - 离线时,从 IndexedDB 读取数据渲染页面;联网后同步变更到服务器(需实现冲突处理逻辑)
例如:文章详情页加载时,先尝试从 IndexedDB 读取,若存在则立即渲染;同时发起网络请求更新本地数据并缓存新版本。
协调 SW 与 IndexedDB 的离线流程
典型离线交互链路如下:
- 用户访问 /article/123 → Service Worker 拦截请求
- 检查 Cache API 是否有该 URL 的 HTML 模板(如有,返回;否则 fallback)
- 页面 JS 启动后,调用
indexedDB.open()获取 article 123 的内容 - 若 DB 中存在,渲染;若不存在,显示“暂无离线内容”或占位提示
- 用户提交评论 → 写入 IndexedDB 待同步队列 → 网络恢复后由后台同步逻辑触发上传
关键点:不要在 Service Worker 中直接操作 IndexedDB(部分浏览器不支持),所有 DB 操作应在页面上下文中完成,SW 仅负责资源缓存与网络代理。


















