Background Sync 允许网页在网络恢复后自动重试失败请求,需注册 Service Worker 并监听 sync 事件,通过 registration.sync.register('tag') 触发,且仅限用户交互调用;Service Worker 中须用 event.waitUntil() 处理并返回 Promise。

Service Worker 的 Background Sync(背景同步)允许网页在用户网络恢复后自动重试之前失败的请求,比如提交表单、上传图片或发送日志。它不保证立即执行,也不适合实时任务,但对提升离线体验非常关键。
前提条件:注册 Service Worker 并启用 sync 功能
Background Sync 依赖 Service Worker 正常运行,且必须在 HTTPS 环境下(本地 localhost 除外)。注册时需确保 Service Worker 文件中监听 sync 事件:
- 主页面调用
navigator.serviceWorker.register('/sw.js')完成注册 - 在
sw.js中添加self.addEventListener('sync', ...)处理器 - 确保页面与 Service Worker 同源,且未被浏览器禁用(如隐私模式可能限制)
注册一次性的后台同步任务
在页面中触发同步前,先检查 API 是否可用,并使用 registration.sync.register() 请求一次同步机会:
- 传入唯一 tag 名称(如
'submit-order'),后续通过该 tag 匹配处理逻辑 - 只能在用户交互(如点击、提交)后调用,不能在页面加载或定时器中直接触发
- 若网络已恢复,系统可能很快触发 sync 事件;若断网,则等待下次上线后执行
if ('serviceWorker' in navigator && 'SyncManager' in window) {<br> navigator.serviceWorker.ready.then(reg => {<br> reg.sync.register('submit-order');<br> });<br>}
在 Service Worker 中处理 sync 事件
Service Worker 收到 sync 事件后,需自行发起网络请求并妥善处理成功/失败:
- 通过
event.tag判断是哪个任务,再执行对应逻辑(如 fetch 提交数据) - 必须返回一个 Promise,且该 Promise 完成后系统才认为本次 sync 结束
- 如果请求失败,可再次调用
registration.sync.register(tag)重试(注意避免无限循环) - 建议搭配 IndexedDB 或 Cache API 存储待同步的数据,避免丢失
self.addEventListener('sync', event => {<br> if (event.tag === 'submit-order') {<br> event.waitUntil(trySyncOrder());<br> }<br>});
进阶技巧与注意事项
- Background Sync 不支持重复周期任务,如需定期同步,请结合 Push API 或客户端定时轮询
- Chrome 和 Edge 支持较好,Firefox 部分支持(需开启实验性标志),Safari 尚未实现
- 系统可能合并多个同 tag 的注册请求,只触发一次 sync,因此 tag 应按业务语义设计(如带用户 ID 或时间戳)
- 调试时可在 Chrome DevTools > Application > Service Workers 中勾选 “Update on reload” 和 “Offline”,再手动触发 sync










