Service Worker不能自动重试XML上传,需先序列化XML存IndexedDB,再通过backgroundSync触发fetch重发;注意CORS预检、离线数据结构、大文件分块及状态管理。

XML上传失败时Service Worker能自动重试吗
不能直接实现。Service Worker本身不提供“后台同步XML上传”的原生能力,sync 事件(sync event)仅在注册了 sync 功能、用户回到网络且浏览器主动触发时才运行,且不携带原始请求上下文——你无法从中拿到待上传的XML内容、headers或认证token。
真正可行的路径是:前端先将XML序列化为字符串或Blob,存入 IndexedDB,再用 backgroundSync(需注册 sync tag)触发重试逻辑;Service Worker内从DB读取、构造 fetch() 请求并发送。
-
sync不是“上传队列”,它只是个信号:浏览器说“现在可以试试了”,具体做什么得你自己写 - XML必须提前序列化好(比如用
new XMLSerializer().serializeToString(doc)),不能在SW里解析DOM或调用XMLHttpRequest - Chrome/Edge支持
backgroundSync,Firefox和Safari目前不支持,需降级为定时轮询或手动触发
如何在Service Worker中安全读取IndexedDB里的XML数据
Service Worker线程可访问 indexedDB,但必须用异步方式打开数据库、事务、获取对象存储。注意:不能使用 await 顶层(需包裹在 self.addEventListener('sync', ...) 回调内),且所有DB操作必须在 event.waitUntil() 中完成,否则SW可能被终止。
ShopNC多用户商城,全新的框架体系,呈现给您不同于以往的操作模式,更简约的界面,更流畅的搜索机制,更具人性化的管理后台操作,更适应现在网络的运营模式解决方案,为您的创业之路打下了坚实的基础,你们的需求就是我们的动力。我们在原有的C-C模式的基础上更增添了时下最流行的团购频道,进一步的为您提高用户的活跃度以及黏性提供帮助。ShopNC商城系统V2.4版本新增功能及修改功能如下:微商城频道A、商城
self.addEventListener('sync', event => {
if (event.tag === 'upload-xml') {
event.waitUntil(
openDB().then(db => {
const tx = db.transaction('uploads', 'readonly');
const store = tx.objectStore('uploads');
return store.getAll(); // 返回所有待上传XML记录
}).then(records => {
return Promise.all(records.map(record =>
fetch('/api/upload', {
method: 'POST',
headers: { 'Content-Type': 'application/xml' },
body: record.xmlString // 已预存的字符串,非Document
}).then(res => {
if (res.ok) {
return deleteFromDB(record.id); // 成功后删记录
}
throw new Error(`HTTP ${res.status}`);
})
));
})
);
}
});
为什么fetch发送XML常被CORS或预检拦住
XML上传本质是带自定义 Content-Type: application/xml 的POST请求,会触发CORS预检(OPTIONS)。若后端未正确响应预检,fetch() 直接失败,且Service Worker里无法捕获网络层错误(如DNS失败),只能靠HTTP状态码和reject判断。
- 确保后端对
OPTIONS返回Access-Control-Allow-Origin、Access-Control-Allow-Methods: POST、Access-Control-Allow-Headers: Content-Type - 避免在
fetch()中设credentials: 'include'同时跨域,否则需后端明确返回Access-Control-Allow-Credentials: true - XML字符串里不能含未转义的
、&等字符,否则后端解析失败——建议用DOMParser+XMLSerializer构建,而非字符串拼接
离线时XML存IndexedDB有哪些坑
存的是原始XML结构,不是引用。容易忽略的关键点:
- XML中相对路径(如
)在离线时无意义,应只存纯数据字段,资源链接需提前转为base64或CDN绝对地址
- 大XML(>5MB)可能超出单条record大小限制(各浏览器不同),需分块存或压缩为
Uint8Array+gzip(但SW里无原生gzip API,需提前压缩) - 时间戳、版本号等元数据必须随XML一起存,否则重试时无法判断是否已过期或重复提交
- 不要用
localStorage替代——SW里无法访问localStorage,且容量小、阻塞主线程









