概览Background Sync 能在网络恢复时触发延后任务。结合 IndexedDB 暂存离线表单与 SW 重试逻辑,可显著提升弱网提交成功率。客户端注册'use client'
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw-sync.js')
}
async function submitOffline(form: HTMLFormElement) {
const fd = new FormData(form)
try {
await fetch('/api/submit', { method: 'POST', body: fd })
} catch {
const db = await openDB('offline', 1)
const tx = db.transaction('forms', 'readwrite')
tx.store.add(Object.fromEntries(fd.entries()))
await tx.done
const reg = await navigator.serviceWorker.ready
await (reg as any).sync.register('submit-forms')
}
}
简易 IndexedDBfunction openDB(name: string, version: number) {
return new Promise<any>((resolve) => {
const req = indexedDB.open(name, version)
req.onupgradeneeded = () => {
const db = req.result
db.createObjectStore('forms', { keyPath: 'id', autoIncrement: true })
}
req.onsuccess = () => resolve(req.result)
})
}
sw-sync.jsself.addEventListener('sync', async (event) => {
if (event.tag === 'submit-forms') {
event.waitUntil((async () => {
const db = await new Promise((resolve) => {
const req = indexedDB.open('offline', 1)
req.onsuccess = () => resolve(req.result)
})
const tx = db.transaction('forms', 'readwrite')
const store = tx.objectStore('forms')
const all = await new Promise((resolve) => {
const req = store.getAll()
req.onsuccess = () => resolve(req.result)
})
for (const item of all) {
const fd = new FormData()
for (const [k, v] of Object.entries(item)) {
if (k !== 'id') fd.append(k, v)
}
try {
await fetch('/api/submit', { method: 'POST', body: fd })
store.delete(item.id)
} catch {}
}
})())
}
})
治理要点对重复重试设定上限与退避,避免服务器压力。数据加密或最小化存储,保护隐私与安全。与 UI 提示协同,告知用户离线暂存与恢复重试状态。验证与指标浏览器:Chrome/Edge 支持 Background Sync;Safari/Firefox 退化为用户触发重试提交成功率在弱网场景显著提升;用户体验更稳定

发表评论 取消回复