【问题标题】:How do I make Worker() work against cross-domain?如何使 Worker() 跨域工作?
【发布时间】:2010-12-11 05:36:52
【问题描述】:

我一直在破解 BeSpin 试图让它在我的 CDN 上运行,并且通过转换为使用 JSONP,我通过了对 theme.less 的 XHR 跨域请求。我遇到的下一个问题是新的 Worker(js_file),其中 js_file 位于不同的域中。

如何/我可以为 Worker() 启用跨域功能吗?

我可以直接给 Worker 源代码吗? (即构建一个嵌入另一个文件的超大 JavaScript 文件)[这不太理想,但应该可以]。

【问题讨论】:

    标签: html bespin


    【解决方案1】:

    试试这个:

    • 用工人代码创建一个函数
    • 获取函数的字符串表示形式(.toString),删除第一行和最后一行。现在你有了一个包含工人代码的字符串
    • 创建一个新的 BlobBuilder (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)
    • 将工作字符串附加到它
    • 调用 getBlob() 获取 blob
    • 使用窗口的 URL (window.URL || window.webkitURL) 使用 createObjectURL 创建一个对象 url
    • 为工作人员使用该网址

    这是代码

    function getUrlForWorker(workerFunction) {
        var BlobBuilder = window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder,
        URL = window.URL || window.webkitURL,
            mainString = workerFunction.toString(),
            bodyString     = mainString.substring( mainString.indexOf("{")+1, mainString.lastIndexOf("}") ),
            bb = new BlobBuilder()
    
        bb.append(bodyString)
    
        return URL.createObjectURL(bb.getBlob())
    }
    

    【讨论】:

    • 这将在heap 中创建一个new Object,而不是使用文件本身,对吗?我问是因为我想使用SharedWorker,它可以跨同一域的选项卡使用,但允许多个域(按照约定)能够将其用作分布式网络中的服务。
    • 丑陋,但它有效。但是,“删除第一行和最后一行”应该是“提取{}之间的函数体”。
    【解决方案2】:

    一种方法是创建我所说的“窗口代理”......

    假设您想在您使用new Worker('at.yourCDN.com/worker.js') 指向的 cdn 上托管一个工作人员。该工作人员可能是 SharedWorker,它允许您在同一域上的不同选项卡保持共享状态。也许您希望这个工作人员也可以访问不同域上的所有选项卡。换句话说,您希望将工作器用作服务/服务器平台。

    问题: 您不能指向位于不同域或使用文件协议的 Worker()/SHAredWorker()。

    这就是我本周要测试的内容:

    1. 为您的 SharedWorker() 提供一个专用位置,例如 CDN 或来自 file:// 协议。
    2. 使用新窗口或 iframe 打开此位置。
    3. 使与该工作人员的所有交互都通过此窗口或 iframe 进行交互,然后将消息转发给工作人员 - 此窗口/iframe 可能只是 DOM 中的一个脚本标签,它可以拉动工作人员,或者是一个内联 -工人。

    详情: 只需让任何需要访问此工作人员的窗口/选项卡运行myWindow.postMessage('my message'),然后让myWindow 对工作人员运行port.postMessage(myMsg)

    就像我说的,我还没有测试过这个,但我希望这会有所帮助。

    另外,我正在寻找一个正在运行的无头浏览器,或者一个带有 CORS 的“永远服务器”,以希望减轻这么多的 iframe 注入和 window.postMessageing。

    我会在找到解决方案后回复。

    ************************************ EDIT ************************************

    我研究了如何使用 SharedWorker 共享状态,不仅适用于同一域上的多个选项卡,而且还可以在多个域之间共享状态 - 使用 SharedWorker 作为本地托管服务。这不是一个解决方案,但这里是演示如何从 FileReader API 构建工作器的代码:

    //DOM 代码:

    <b>1</b>
    <input id="uploadImage" type="file" name="myPhoto" onchange="onSelect();" autofocus="true" />
    <script>
    var fReader = new FileReader();
    fReader.onload = function(e){
      var blob = new Blob([e.target.result], {type: 'text/javascript'});
      var blobURL = URL.createObjectURL(blob);
      var w = new SharedWorker(blobURL);
      w.port.onmessage = function(e){
        console.log('%%^', e);
      };
      w.port.start();
      w.port.postMessage('Echo');
    };
    function onSelect(e){
      var file = document.getElementById("uploadImage").files[0];
      var dataURL = fReader.readAsText(file);
    }
    </script>
    

    //桌面上工人文件的代码:

    var ports = ports || [];
    self.onconnect = function(e){
      var port = e.ports[0];
      ports.push(port);
    
      port.addEventListener('message', function(e){
        port = e.target;
        ports.forEach(function(p){
          p.postMessage('gWorker:: ' + e.data);
        });
      }, false);
    
      port.start();
    };
    

    可能的解决方案:

    就 CDN-Worker 而言,我们似乎不能使用 FileReader/BlobBuilder,因为它们会在本地 heap 中创建我们的“自己的”worker object。似乎我们不能将CORS 用作启用CORS 的服务器,可以通过XMLHttpRequest 推销工作代码,但创建new Worker('http://from.mycors.com/enabled/server') 失败,并出现与我们看到的相同的“DOM Exception 18SecurityError太多了。

    最好的解决方案可能是上面详述的“Window-Proxy”方法(@​​987654341@ 到具有自己工作器的另一台服务器上的 iframe,window.onmessage 向工作器转发消息)。请注意,如果您计划利用 http 以外的其他 Internet 协议,window.postMessage 将使用 http。

    或者,有些人已经诉诸于运行google-chrome --allow-file-access-from-files——但这对于生产场景来说显然是有风险的。

    另一种途径是为 WebRTC 架构创建一个集合点,这可能是最健壮的。

    我希望这可以为您节省大量不必要的研究,并激发更好的解决方案。

    干杯,

    【讨论】:

      猜你喜欢
      • 2022-07-06
      • 2013-10-16
      • 1970-01-01
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 2013-02-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多