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

React项目低版本Chromium中Service Worker异常问题求助

React项目Service Worker在Chromium 49(Windows XP)下的兼容问题

环境与异常表现

  • 正常运行环境:Chromium 102.0.5005.63 + Windows 7
  • 异常环境:Chromium 49.0.2623.75 + Windows XP
  • 报错信息:

Uncaught TypeError: Cannot read property of 'set' of undefined
ServiceWorker script evaluation failed

前置说明

  • 项目通过HTTPS协议加载
  • Chromium 49规范上支持Service Worker,且生产环境中"serviceWorker" in navigator返回true
  • 已更新package.json中的browserslist配置,执行npx browserslist确认chrome 49在列表内:
"browserslist": {
    "production": [
      "> 0.04%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  • 自定义的service-worker.js和serviceWorkerRegistration.js中未使用.set方法

更新1:报错根源定位

报错来自Workbox生成的createCacheKey方法,其中cacheKeyURL.searchParams在Chromium 49中为undefined,相关代码片段:

var REVISION_SEARCH_PARAM = '__WB_REVISION__';

function createCacheKey(entry) {
  // ... 省略其他逻辑代码 ...

  // 构建带版本号的缓存键URL
  var cacheKeyURL = new URL(url, location.href);
  var originalURL = new URL(url, location.href);
 
  cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);
  return {
    cacheKey: cacheKeyURL.href,
    url: originalURL.href
  };
}

更新2:临时修复后的新问题

手动在build目录的service-worker.js中添加兼容代码后,原报错消失,但出现ServiceWorker failed to install无额外提示,临时代码:

var cacheKeyURL = new URL(url, location.href);
var originalURL = new URL(url, location.href);

// 临时兼容代码
if (!cacheKeyURL['searchParams']){
  var urlParams = new URLSearchParams(location.search);
  cacheKeyURL.searchParams = urlParams;
}

cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);

解决方案

1. 修复searchParams兼容逻辑

Chromium 49的URL对象原生不支持searchParams属性,且该属性为只读,强行赋值会导致后续异常。正确的兼容方式是直接拼接参数到URL的search部分:

var cacheKeyURL = new URL(url, location.href);
var originalURL = new URL(url, location.href);

// 兼容Chrome 49的searchParams缺失问题
if (!cacheKeyURL.searchParams) {
  // 判断原有search是否存在,决定用?还是&分隔
  var separator = cacheKeyURL.search ? '&' : '?';
  cacheKeyURL.href += separator + REVISION_SEARCH_PARAM + '=' + encodeURIComponent(revision);
} else {
  cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);
}

return {
  cacheKey: cacheKeyURL.href,
  url: originalURL.href
};

2. 自动注入兼容代码到构建流程

由于service-worker.js是Workbox自动生成的,不建议直接修改node_modules源码,推荐以下两种自动注入方式:

方式1:通过Webpack自定义插件(适用于Create React App)

  1. 项目根目录创建workbox-compat-plugin.js:
module.exports = class InjectSearchParamsFix {
  generateBundle(options, bundle) {
    const swFile = bundle['service-worker.js'];
    if (!swFile) return;

    // 匹配目标代码片段并替换
    const targetCode = `var cacheKeyURL = new URL(url, location.href);
  var originalURL = new URL(url, location.href);
 
  cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);`;
    
    const fixedCode = `var cacheKeyURL = new URL(url, location.href);
  var originalURL = new URL(url, location.href);
 
  // 兼容Chrome 49的searchParams缺失问题
  if (!cacheKeyURL.searchParams) {
    var separator = cacheKeyURL.search ? '&' : '?';
    cacheKeyURL.href += separator + REVISION_SEARCH_PARAM + '=' + encodeURIComponent(revision);
  } else {
    cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);
  }`;

    swFile.source = swFile.source.replace(targetCode, fixedCode);
  }
};
  1. 使用react-app-rewired修改Webpack配置:
    • 安装依赖:npm install react-app-rewired --save-dev
    • 创建config-overrides.js:
const InjectSearchParamsFix = require('./workbox-compat-plugin');

module.exports = function override(config) {
  // 添加自定义插件到Webpack插件列表
  config.plugins.push(new InjectSearchParamsFix());
  return config;
};
  1. 修改package.json的脚本:
"scripts": {
  "start": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test"
}

方式2:Post-Build脚本(简单直接)

  1. 项目根目录创建fix-sw-compat.js:
const fs = require('fs');
const path = require('path');

const swPath = path.join(__dirname, 'build', 'service-worker.js');
let swCode = fs.readFileSync(swPath, 'utf8');

const targetCode = `var cacheKeyURL = new URL(url, location.href);
  var originalURL = new URL(url, location.href);
 
  cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);`;

const fixedCode = `var cacheKeyURL = new URL(url, location.href);
  var originalURL = new URL(url, location.href);
 
  // 兼容Chrome 49的searchParams缺失问题
  if (!cacheKeyURL.searchParams) {
    var separator = cacheKeyURL.search ? '&' : '?';
    cacheKeyURL.href += separator + REVISION_SEARCH_PARAM + '=' + encodeURIComponent(revision);
  } else {
    cacheKeyURL.searchParams.set(REVISION_SEARCH_PARAM, revision);
  }`;

swCode = swCode.replace(targetCode, fixedCode);
fs.writeFileSync(swPath, swCode);
console.log('Service Worker Chrome 49兼容修复完成');
  1. 修改package.json的build脚本:
"scripts": {
  "build": "react-scripts build && node fix-sw-compat.js"
}

内容的提问来源于stack exchange,提问作者M.H.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 13:01:26