You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React PWA中Workbox Background Sync请求体为空问题求助

Workbox Background Sync 重放请求时请求体为空问题

问题背景

我们内部的React PWA日均服务700名用户,采用Workbox Background Sync处理文件上传。多数场景功能正常:用户离线时发起的上传请求会存入indexedDB,恢复网络后自动重放。但部分请求出现异常:请求已正确存入indexedDB,但重放调用API时请求体为空(见截图)。原请求无问题,应用已上线近一年且经过充分测试,文件采用Base64格式上传,未使用formData。

路由注册代码

const routesToRegister = [
{
    pattern: /.*\/file/,
    method: ['POST', 'DELETE'],
},
{
    pattern: /.*\/post_it/,
    method: ['POST', 'DELETE'],
},
{
    pattern: /.*\/report/,
    method: ['POST'],
},
{
    pattern: /.*\/arrival/,
    method: ['PATCH'],
},
{
    pattern: /.*\/product/,
    method: ['PATCH'],
},
];
routesToRegister.forEach((route) => {
  route.method.forEach((method) => {
    registerRoute(
        route.pattern,
        new NetworkOnly({
            plugins: [bgSyncPlugin],
        }),
        method,
    );
  });
});

问题原因

Workbox默认的请求克隆逻辑在处理**可读流(ReadableStream)**类型的请求体时,会因为流被一次性消费导致重放时无法读取内容。Base64格式的请求体如果以流的形式发送,第一次存入indexedDB时流已被读取,重放时就会出现空请求体的情况。

解决方案

通过自定义requestWillReplay回调,手动克隆请求并重新构建可重复读取的请求体:

const bgSyncPlugin = new BackgroundSyncPlugin('myQueue', {
  requestWillReplay: async ({ request }) => {
    // 针对POST/PATCH这类带请求体的方法处理
    if (['POST', 'PATCH'].includes(request.method)) {
      // 读取请求体内容并转为字符串
      const bodyContent = await request.text();
      // 重新创建Request对象,确保请求体可重复使用
      return new Request(request.url, {
        method: request.method,
        headers: new Headers(request.headers),
        body: bodyContent,
        mode: request.mode,
        credentials: request.credentials,
        cache: request.cache,
        redirect: request.redirect,
        referrer: request.referrer,
      });
    }
    return request;
  },
});

// 原路由注册代码保持不变
const routesToRegister = [
// ... 原有路由配置
];
routesToRegister.forEach((route) => {
  route.method.forEach((method) => {
    registerRoute(
        route.pattern,
        new NetworkOnly({
            plugins: [bgSyncPlugin],
        }),
        method,
    );
  });
});

额外验证步骤

  • 检查indexedDB存储:在浏览器DevTools的「Application > IndexedDB > workbox-background-sync > requests」中查看请求的body字段,确认存储的内容完整。
  • 确认请求头:确保Content-Type与后端预期一致(比如Base64上传用text/plain或application/json),避免解析失败。
  • 跨域配置检查:如果API是跨域的,确保请求的mode和credentials设置正确,重放时不会因跨域策略丢失请求体。

内容的提问来源于stack exchange,提问作者Floran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 15:57:47