service worker 不能直接操作 indexeddb,需与页面 js 分工协作:页面负责 indexeddb 初始化、读写及同步逻辑,sw 负责拦截请求、协调响应并缓存兜底,离线同步由页面主动触发。

Service Worker 本身不能直接操作 IndexedDB —— 它运行在独立线程,而 IndexedDB 的 open 操作必须由页面主线程(或 Worker)发起,且不支持在 Service Worker 中调用 indexedDB.open()。所以“配合”不是指 SW 写数据,而是分工协作:页面 JS 负责读写 IndexedDB,Service Worker 负责拦截请求、判断是否可用本地数据、并合成响应。
页面 JS 负责 IndexedDB 的初始化与存取
数据库连接和业务逻辑必须放在页面脚本中,不能塞进 sw.js:
- 在页面加载后立即调用
indexedDB.open(),建好 objectStore(如posts、pending-actions),设好主键(id)和索引(如updatedAt、syncStatus) - 用户提交表单或编辑内容时,把数据连同操作类型(
op: 'create')、同步状态(syncStatus: 'pending')一起写入 DB - 读取时用
get()或带索引的openCursor(),比如查syncStatus === 'pending'的待同步记录
Service Worker 拦截 API 请求并代理响应
当页面发起 fetch('/api/note/123') 时,SW 在 fetch 事件中决定怎么回应:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 若 URL 匹配
/api/,不转发网络请求,而是调用postMessage通知页面 JS 查询 IndexedDB - 页面 JS 查到数据后,通过
MessageChannel或clients.matchAll()把结果发回 SW - SW 构造一个
Response(用new Response(JSON.stringify(data), { headers })),返回给原 fetch 请求 - 对 POST /api/note,SW 可解析 request.body,再 postMessage 让页面存入 DB,并返回模拟成功响应
离线优先加载流程要分层兜底
用户访问 /note/123 页面时,实际是三段协同:
- SW 先用
caches.match()返回已缓存的 HTML 模板(App Shell),保证界面秒开 - 页面 JS 加载后立刻查 IndexedDB,有数据就渲染;没数据则显示 loading 或 fallback 离线页
- 同时发起网络请求尝试刷新——成功则更新本地 DB 和缓存;失败也不中断体验
联网后自动同步靠页面主动触发
同步不是 SW 自动做的,而是页面监听网络状态后驱动:
- 监听
navigator.onLine或用 Background Sync API 触发同步任务 - 按
updatedAt索引反向遍历syncStatus === 'pending'的记录 - 逐条发请求到服务端,接口需幂等(建议带
X-Request-ID去重) - 成功后更新本地记录的
syncStatus和serverId;失败则记错误次数,超限转为手动同步提示
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










