ServiceWorker注册失败:跨域脚本URL与当前源不匹配问题求助
问题概述
使用Create React App构建的React前端站点(域名:https://reactjscms.devdigdev.com),尝试从外部域名https://unpkg.com注册ServiceWorker时失败,报错信息:
ServiceWorker registration failed- DOMException: Failed to register a ServiceWorker: The origin of the provided scriptURL ('https://unpkg.com') does not match the current origin ('https://reactjscms.devdigdev.com').
问题原因
浏览器的ServiceWorker安全规则明确要求:ServiceWorker脚本必须与当前页面同源。若要加载跨域的ServiceWorker脚本,需满足两个严格条件:
- 远程服务器返回
Access-Control-Allow-Origin头,允许当前站点跨域访问 - 远程服务器返回
Service-Worker-Allowed头,指定该SW允许控制的域名范围
第三方CDN(如unpkg)通常不会为这类场景配置上述响应头,因此直接注册跨域SW的方案根本不可行。
解决方案
你已经编写了本地的service-worker.js文件,直接使用这个本地脚本即可解决问题,步骤如下:
1. 修改index.html中的ServiceWorker注册代码
将注册跨域SW的代码替换为指向本地脚本:
<script> if ("serviceWorker" in navigator) { window.addEventListener("load", function () { navigator.serviceWorker .register('/service-worker.js', { scope: '/' }) .then(function (registration) { console.log("ServiceWorker registration successful with scope: ", registration.scope); }) .catch(function (err) { console.log("ServiceWorker registration failed- ", err); }); }); } </script>
'/service-worker.js':指向项目根目录下的本地ServiceWorker脚本(Create React App会自动处理该文件的打包部署){ scope: '/' }:指定SW控制当前站点的所有路径,可省略(默认值即为当前域的根路径)
2. 确保Create React App的PWA配置正确
如果你的项目不是基于CRA的PWA模板创建的,需要补充以下配置:
- 确认项目已安装workbox相关依赖(你的
service-worker.js已使用workbox,依赖应该已存在) - 在
package.json中添加PWA基础配置(若没有的话):
{ "homepage": "https://reactjscms.devdigdev.com", "dependencies": { "workbox-core": "^7.0.0", "workbox-expiration": "^7.0.0", "workbox-precaching": "^7.0.0", "workbox-routing": "^7.0.0", "workbox-strategies": "^7.0.0", "workbox-recipes": "^7.0.0", "workbox-cacheable-response": "^7.0.0" } }
3. 构建并部署项目
执行npm run build构建生产版本,将构建后的文件部署到你的服务器。Create React App会自动将service-worker.js打包到构建目录中,并确保其可以被正确访问。
验证
部署完成后,打开站点的开发者工具(F12),进入Application > Service Workers面板,查看是否显示注册成功的ServiceWorker,同时检查控制台是否输出成功日志。
内容的提问来源于stack exchange,提问作者Rishabh Kapoor

