Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML5 Web Workers work in Firefox 4, but not in Chrome 12.0.742.122

When I tried to play around with Web Workers feature in HTML5, my firefox works happily but chrome complains that:

Uncaught TypeError: Cannot call method 'postMessage' of undefined xstartWorkerworker.html:7 (anonymous function)worker.html:1 onclickworker.html:2

worker.html

<button onclick="xstartWorker()">Start worker</button>
<output id="result"></output>
<script>
function xstartWorker()
{
  worker.postMessage({'cmd': 'startWorker', 'msg': 'Start now!'});
}

var worker = new Worker('worker.js');

worker.addEventListener('message', function(e)
  {
      document.getElementById('result').textContent = e.data;
  }
  , false);
</script>

worker.js

self.addEventListener('message', function(e)
{
  var data = e.data;
  switch (data.cmd)
  {
    case 'startWorker':
      self.postMessage('worker thread start now:' + data.msg);
      break;
    default:
      self.postMessage('default');
  }
}
, false);

What I can do to make it works in chrome?

BTW, when I tried out the sample at http://playground.html5rocks.com/#inline_workers and this time chrome works, but firefox complains that

Error: worker is undefined Source File: http://playground.html5rocks.com/ Line: 39

like image 955
janetsmith Avatar asked Jul 25 '11 02:07

janetsmith


2 Answers

Chrome can use worker locally without the --allow-file-access-from-files. The worker needs to be loaded as a blob.

Example:

<body>
    <button>Start</button>
    <div id="output"></div>
    <script id="worker_1" type="text/js-worker">
        importScripts(base_url + '/worker_lib2.js');

        function run(event) {
            var msg = event.data;
            this.postMessage({ answer: hello(event.data.name)});
        }

        this.addEventListener('message', run, false);
    </script>

    <script>
        var base_url = window.location.href.replace(/\\/g,'/').replace(/\/[^\/]*$/, '');
        var array = ['var base_url = "' + base_url + '";' + $('#worker_1').html()];
        var blob = new Blob(array, {type: "text/javascript"});

        $('button').click(function() {
            var url = window.URL.createObjectURL(blob);
            console.log(url);
            var worker = new Worker(url);
            worker.addEventListener('message', function(event) {
                $('#output').html(event.data.answer);
            }, false);
            worker.postMessage({
                name: 'Yannis'
            });
        });
    </script>
</body>

The file worker_lib2.js :

function hello(msg) {
    return 'Hello... ' + msg;
}
like image 94
jlguenego Avatar answered Apr 06 '23 10:04

jlguenego


I'm guessing you're trying to run this on your local machine, not on a webserver. Workers are restricted by the Same Origin Policy, but as the linked Wikipedia page notes,

The behavior of same-origin checks and related mechanisms is not well-defined in a number of corner cases, such as for protocols that do not have a clearly defined host name or port associated with their URLs (file:, data:, etc.).

Loading a local file, even with a relative URL, is the same as loading a file with the file: protocol. So my guess is that the problem is that you're trying to load worker.js as a local file - Chrome doesn't like this (for some good security reasons), though you can force the issue by starting Chrome like this: chrome.exe --allow-file-access-from-files

Alternatively, try serving your script on a local or remote webserver and see if that fixes the problem. (If you have Python installed, you can go to the directory in question and run python -m SimpleHTTPServer 8000, then go to http://localhost:8000/ in your browser).

like image 28
nrabinowitz Avatar answered Apr 06 '23 09:04

nrabinowitz