如何在同页面Web Worker中使用XHR且规避CORS预请求?
解决方法:用Blob URL替代data: URL创建同源Worker
- 核心逻辑:Blob URL会继承生成它的页面的源,浏览器会把这类Worker判定为同源上下文,不会触发CORS预请求,和单独文件的Worker行为完全一致。
- 具体实现步骤:
- 把Worker的代码写成字符串形式;
- 将字符串包装成
Blob对象,指定MIME类型为text/javascript; - 用
URL.createObjectURL()生成Blob URL,以此创建Worker。
- 代码示例:
// 你的Worker业务代码字符串 const workerCode = ` self.addEventListener('message', (e) => { const xhr = new XMLHttpRequest(); xhr.open('GET', '/your-target-path', true); xhr.onload = () => { if (xhr.status >= 200 && xhr.status < 300) { self.postMessage({ ok: true, data: xhr.responseText }); } else { self.postMessage({ ok: false, msg: '请求失败' }); } }; xhr.onerror = () => { self.postMessage({ ok: false, msg: '网络错误' }); }; xhr.send(); }); `; // 生成Blob URL并创建Worker const workerBlob = new Blob([workerCode], { type: 'text/javascript' }); const workerUrl = URL.createObjectURL(workerBlob); const myWorker = new Worker(workerUrl); // 监听Worker返回结果,用完释放URL避免内存泄漏 myWorker.addEventListener('message', (res) => { console.log('Worker返回:', res.data); URL.revokeObjectURL(workerUrl); }); // 触发Worker执行请求 myWorker.postMessage('start-fetch'); - 兼容性确认:
- Chromium 125.0.6422.112:完全支持该方案,同源判定正常,无OPTIONS预请求;
- Firefox 115.11.0esr:同样兼容,XHR请求可直接发送,无需服务器返回CORS头。
为什么data: URL会失败?
data: URL的源被浏览器标记为null,属于跨源上下文,所以Worker内的XHR会被判定为跨域请求,触发OPTIONS预请求。而你的嵌入式服务器不支持CORS逻辑,直接导致预请求失败。Blob URL则完全继承页面的同源信息,Worker运行在同源环境下,请求行为和单独文件的Worker一致。
内容的提问来源于stack exchange,提问作者Stefan Hegny
相关产品推荐
相关产品推荐

