使用Data URL创建的Web Worker丢失安全上下文问题咨询
问题分析与解答
这是Chromium浏览器的已知行为,并非你的操作错误,也不是规范本身的问题。
原因说明
按照安全上下文的规范,Worker的安全上下文应当继承自创建它的主页面。但Chromium系浏览器会将通过data: URL创建的Web Worker判定为非安全上下文——这是因为Chromium把data:协议视为非安全源,即便主页面处于安全上下文,也不会让Worker继承该属性。
复现代码验证
你提供的代码可以直接复现该问题:
<!DOCTYPE html> <html> <head> <title>Worker Security Flaw?</title> <meta charset="UTF-8"> <script> function main(){ out.textContent= 'window.isSecureContext= '+isSecureContext; let worker= new Worker('data:text/javascript,onmessage= function(e){postMessage({flag:isSecureContext});};'); worker.onmessage= function(e){out.textContent+= ', worker.isSecureContext= '+e.data.flag;}; worker.postMessage({}); } </script> </head> <body onload="main();"> <output id="out"></output> </body> </html>
运行后会显示主页面isSecureContext为true,但Worker中的值为false,这完全符合Chromium当前的处理逻辑。
临时解决方案
如果需要让Worker和主页面保持一致的安全上下文,可以改用以下两种方式:
- 将Worker代码保存为独立的
.js文件,通过相对路径加载,而非data:URL。 - 若必须内嵌Worker代码,使用
BlobURL替代data:URL,示例代码如下:
function main(){ out.textContent= 'window.isSecureContext= '+isSecureContext; const workerCode = `onmessage= function(e){postMessage({flag:isSecureContext});};`; const blob = new Blob([workerCode], {type: 'text/javascript'}); const workerUrl = URL.createObjectURL(blob); let worker= new Worker(workerUrl); worker.onmessage= function(e){out.textContent+= ', worker.isSecureContext= '+e.data.flag;}; worker.postMessage({}); // 使用后释放Blob URL资源 worker.addEventListener('terminate', () => URL.revokeObjectURL(workerUrl)); }
这种方式下,Worker会正常继承主页面的安全上下文,isSecureContext值将和主页面保持一致。
内容的提问来源于stack exchange,提问作者eiffie
相关产品推荐
相关产品推荐

