94

文字列 (POST リクエストを介して提供される) から Web ワーカーを作成するにはどうすればよいですか?

考えられる方法の 1 つは、サーバーの応答からデータ URI を作成し、それを Worker コンストラクターに渡すことですが、一部のブラウザーでは許可されていないと聞いています。これは、同一オリジン ポリシーによるものです。

MDN は、データ URI のオリジン ポリシーに関する不確実性を述べています

注: Worker コンストラクターのパラメーターとして渡される URI は、同一オリジン ポリシーに従う必要があります。現在、データ URI が同じオリジンであるかどうかについて、ブラウザー ベンダー間で意見の相違があります。Gecko 10.0 (Firefox 10.0 / Thunderbird 10.0) 以降では、ワーカーの有効なスクリプトとしてデータ URI を使用できます。他のブラウザは同意しない場合があります。

whatwg で議論している投稿もあります。

4

10 に答える 10

158

概要

  • blob:Chrome 8 以降、Firefox 6 以降、Safari 6.0 以降、Opera 15 以降の場合
  • data:application/javascriptオペラ 10.60 - 12 の場合
  • evalそれ以外の場合 (IE 10 以降)

URL.createObjectURL(<Blob blob>)文字列から Web ワーカーを作成するために使用できます。BLOB は、非推奨BlobBuilderのAPIまたはコンストラクターを使用して作成できます。Blob

デモ: http://jsfiddle.net/uqcFM/49/

// URL.createObjectURL
window.URL = window.URL || window.webkitURL;

// "Server response", used in all examples
var response = "self.onmessage=function(e){postMessage('Worker: '+e.data);}";

var blob;
try {
    blob = new Blob([response], {type: 'application/javascript'});
} catch (e) { // Backwards-compatibility
    window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
    blob = new BlobBuilder();
    blob.append(response);
    blob = blob.getBlob();
}
var worker = new Worker(URL.createObjectURL(blob));

// Test, used in all examples:
worker.onmessage = function(e) {
    alert('Response: ' + e.data);
};
worker.postMessage('Test');

互換性

Web ワーカーは、次のブラウザーソースでサポートされています。

  • クロム 3
  • Firefox 3.5
  • IE10
  • オペラ 10.60
  • サファリ4

Blobこのメソッドのサポートは、 API とメソッドのサポートに基づいていますURL.createObjectUrlBlob互換性:

  • Chrome 8 以降 ( WebKitBlobBuilder)、20 以降 (Blobコンストラクター)
  • Firefox 6 以降 ( MozBlobBuilder)、13 以降 (Blobコンストラクター)
  • Safari 6+ (Blobコンストラクター)

IE10 は と をサポートしMSBlobBuilderていURL.createObjectURLます。ただし、blob:-URL から Web Worker を作成しようとすると、SecurityError がスローされます。

URLOpera 12 はAPIをサポートしていません。のこのハッキングのURLおかげで、一部のユーザーはオブジェクトの偽バージョンを持っている可能性があります。browser.js

フォールバック 1: データ URI

WorkerOpera はコンストラクタへの引数として data-URI をサポートしています。注:特殊文字(#や など)をエスケープすることを忘れないでください%

// response as defined in the first example
var worker = new Worker('data:application/javascript,' +
                        encodeURIComponent(response) );
// ... Test as defined in the first example

デモ: http://jsfiddle.net/uqcFM/37/

フォールバック 2: 評価

evalSafari (<6) および IE 10 のフォールバックとして使用できます。

// Worker-helper.js
self.onmessage = function(e) {
    self.onmessage = null; // Clean-up
    eval(e.data);
};
// Usage:
var worker = new Worker('Worker-helper.js');
// `response` as defined in the first example
worker.postMessage(response);
// .. Test as defined in the first example
于 2012-04-29T12:53:13.127 に答える
2

良い答えです。私は今日、フォールバック機能を使用できない Web ワーカーを作成しようとしたとき (つまり、メイン スレッドでワーカー スクリプトを実行するとき) に、同様の問題に取り組んできました。このスレッドはトピックに関連しているため、ここで解決策を提供すると思いました。

    <script type="javascript/worker">
        //WORKER FUNCTIONS
        self.onmessage = function(event) {
            postMessage('Hello, ' + event.data.name + '!');
        }
    </script>

    <script type="text/javascript">

        function inlineWorker(parts, params, callback) {

            var URL = (window.URL || window.webkitURL);

            if (!URL && window.Worker) {

                var worker = new window.Worker(URL.createObjectURL(new Blob([parts], { "type" : "text/javascript" })));

                worker.onmessage = function(event) {
                  callback(event.data);
                };

                worker.postMessage(params);

            } else {

                var postMessage = function(result) {
                  callback(result);
                };

                var self = {}; //'self' in scope of inlineWorker. 
                eval(parts); //Converts self.onmessage function string to function on self via nearest scope (previous line) - please email chrisgwgreen.site@gmail.com if this could be tidier.
                self.onmessage({ 
                    data: params 
                });
            }
        }

        inlineWorker(
            document.querySelector('[type="javascript/worker"]').textContent, 
            {
                name: 'Chaps!!'
            },
            function(result) {
                document.body.innerHTML = result;
            }
        );

    </script>
</body>

于 2013-06-18T23:15:34.940 に答える
-1

私の小さなプラグインを使用してください https://github.com/zevero/worker-create

var worker_url = Worker.create("self.postMessage('Example post from Worker');");
var worker = new Worker(worker_url);

しかし、関数を与えることもできます。

于 2015-10-18T12:00:50.307 に答える