Web Worker 必须加载与主页面完全同源的脚本,即协议、域名、端口三者全部一致,否则浏览器直接抛出 SecurityError;因其共享页面 origin,可访问 Cookie、fetch 等敏感资源,跨域加载会破坏 CSP 与沙箱隔离。

Web Worker 必须加载与主页面完全同源的脚本——即协议、域名、端口三者全部一致,否则浏览器会直接抛出 SecurityError,不发起任何网络请求。这不是兼容性问题,而是强制执行的安全边界。
同源策略对 Worker 的具体约束
Worker 脚本 URL 必须与当前页面 origin 完全匹配:
- HTTP 页面不能加载 HTTPS Worker,反之亦然(协议不同即跨域)
-
https://example.com和https://api.example.com因子域名不同,视为跨源 -
http://localhost:3000与http://localhost:5000端口不同,同样被拒绝 - 即使使用相对路径
./worker.js,其解析结果也必须落在当前页面 origin 下
为什么 Worker 要严格 enforce 同源?
Worker 虽运行在独立线程、不接触 DOM,但它共享页面的 origin 上下文,具备访问敏感资源的能力:
- 可读写同源 Cookie(含 HttpOnly 以外的会话凭证)
- 能调用
fetch()发起带凭据的请求,访问同源 API 或 IndexedDB - 可通过
importScripts()加载其他脚本,形成执行链路 - 若允许跨域加载,攻击者可借 CDN 托管恶意 Worker,将其注入你站点的可信执行环境
常见开发阶段误报场景
本地开发时,看似“只是换了个端口”,却常触发跨域错误:
- Vite 或 Webpack Dev Server 开启了 HTTPS 代理,但 Worker 构造函数仍用 HTTP 地址
- Worker 内部使用
importScripts('https://unpkg.com/xxx.js')直接加载外部库 - 通过 Blob URL 创建 Worker,但 Blob 内容中又包含跨域
importScripts调用 - 微前端子应用尝试复用主应用托管的 Worker 脚本,因子域不同被拦截
安全可行的应对方式
不绕过策略本身,而是让脚本始终处于同源上下文中:
- 统一开发服务端口,或配置反向代理(如 Vite 的
proxy),使 API 和 Worker 脚本都走同一 origin - 用 Blob URL 动态生成 Worker:将 Worker 逻辑写成字符串,转为 Blob,再生成
URL.createObjectURL(blob)传入new Worker() - 若需加载远程逻辑,先通过同源 fetch 获取脚本内容,再注入 Blob;注意仍需校验来源可信度
- 避免在 Worker 中硬编码跨域地址,所有资源引用应基于当前页面 origin 解析

















