启用跨源隔离策略时如何正常使用Web Worker
问题原因
开启Cross-Origin-Opener-Policy: same-origin + Cross-Origin-Embedder-Policy: require-corp实现跨源隔离后,浏览器会强制校验页面加载的所有子资源的嵌入权限,Web Worker脚本也在校验范围内。你现在的test.js虽然和页面同域,但服务端返回这个js文件时没带要求的跨源资源策略头,直接被浏览器拦截,所以不会执行,控制台也看不到预期输出。
可行解决方式
根据你的部署场景选任意一种即可,两种方式都完全满足SharedArrayBuffer的运行要求,不会影响业务逻辑:
- 给Worker资源配置合规的响应头
这是最规范的静态资源部署方案。如果你用Nginx、Apache等Web服务器托管静态js文件,直接给站点下js资源的响应加上Cross-Origin-Resource-Policy: same-origin头就能解决问题。
不想修改Web服务器配置的话,也可以把Worker脚本改成PHP入口输出,手动给响应加所需头,示例代码如下:
前端创建Worker时把地址改成对应PHP路径即可:<?php // 新建worker.php替代原test.js header('Content-Type: application/javascript; charset=UTF-8'); header('Cross-Origin-Resource-Policy: same-origin'); ?> console.log("test.js is loaded") // 原有Worker的全部业务逻辑,包括SharedArrayBuffer相关代码都写在这里new Worker("/worker.php") - 使用内联Blob形式创建Worker
不想额外调整资源配置的话,可以直接把Worker代码转成Blob URL生成内联Worker,这种方式生成的Worker和当前页面天然同源,不需要额外配置资源头,示例代码如下:const workerCode = ` console.log("test.js is loaded") // 此处填写原test.js里的全部业务逻辑 `; const workerBlob = new Blob([workerCode], { type: 'application/javascript' }); const workerUrl = URL.createObjectURL(workerBlob); const worker = new Worker(workerUrl); // Worker使用完成后记得调用revoke释放内存,避免不必要的资源占用 // URL.revokeObjectURL(workerUrl)
额外注意事项
- 如果你的Worker内部还会通过
importScripts、fetch等方式加载其他子资源,这些资源同样要满足跨源隔离校验规则:同源资源需要携带Cross-Origin-Resource-Policy: same-origin头,跨源资源需要配置匹配当前源的CORS头,同时携带Cross-Origin-Resource-Policy: cross-origin头。 - 如果需要加载跨源部署的Worker脚本,除了上述资源头配置外,创建Worker时还要根据凭证传递需求配置
credentials参数。
内容的提问来源于stack exchange,提问作者張俊芝
相关产品推荐
相关产品推荐

