如何使Worker()对跨域工作?

时间:2010-12-11 05:36:52

标签: html5 bespin

我一直在攻击BeSpin,试图让它在我的CDN上工作,我通过转换为使用JSONP而通过了XHR跨域请求的主题。我遇到的下一个问题是新的Worker(js_file),其中js_file位于不同的域中。

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

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

2 个答案:

答案 0 :(得分:2)

试试这个:

  • 使用工作人员的代码创建一个函数
  • 获取函数的字符串表示形式(.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())
}

答案 1 :(得分:0)

一种方法是创建我称之为“Window-Proxy”....

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

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

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

  1. 为您的SharedWorker()提供专用位置,例如CDN或文件://协议。
  2. 使用新窗口或iframe打开此位置。
  3. 让这个工作者的所有交互通过这个窗口或iframe进行交互,然后iframe将消息转发给工作者 - 这个窗口/ iframe可能只是DOM中的一个脚本标记,它可以拉动工作者,也可以是内联的 - 工人。
  4. 详细说明: 只需让任何需要访问此工作人员的窗口/标签运行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,因为这些会在本地worker object中创建我们自己的heap 。我们似乎无法使用CORS作为启用了CORS的服务器,可以通过XMLHttpRequest推销工作人员代码,但是创建new Worker('http://from.mycors.com/enabled/server')会失败并显示相同的“DOM Exception 18 } SecurityError我们已经看过太多了。

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

    或者,有些人已经开始使用google-chrome --allow-file-access-from-files - 但这对于生产场景来说显然是有风险的。

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

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

    干杯,