2011-07-25 8 views
8

Cuando traté de jugar con Web Workers figurar en HTML5, mi firefox funciona felizmente, pero se queja de que el cromo:Web Workers HTML5 funciona en Firefox 4, pero no en Chrome 12.0.742.122

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); 

lo que puedo hacer para que funciona en Chrome?

Por cierto, cuando probé la muestra a http://playground.html5rocks.com/#inline_workers y esta vez las obras de cromo, pero se queja de que Firefox

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

+1

Quizás quiso publicar el código correcto para worker.js? Parece que has reposteado worker.html por error. – nrabinowitz

+0

Sí, tienes razón. Mi error. Pegué el worker.js ahora. – janetsmith

Respuesta

6

supongo que está tratando de ejecutar esto en su máquina local, no en un servidor web. Los trabajadores están restringidas por el Same Origin Policy, pero como la página de notas vinculadas Wikipedia,

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.).

cargar un archivo local, incluso con una dirección URL relativa, es la misma que la carga de un archivo con el protocolo file:. Así que supongo que el problema es que estás tratando de cargar worker.js como un archivo local - A Chrome no le gusta esto (por algunas buenas razones de seguridad), aunque puedes forzar el problema iniciando Chrome así: chrome.exe --allow-file-access-from-files

Como alternativa, intente publicar su script en un servidor web local o remoto y vea si eso soluciona el problema. (Si tiene Python instalado, puede ir al directorio en cuestión y ejecutar python -m SimpleHTTPServer 8000, luego vaya a http://localhost:8000/ en su navegador).

+0

¡Probé tu sugerencia con Tomcat 7, funciona perfectamente! – janetsmith

+0

Supongo que no podría poner un enlace a esas "buenas razones de seguridad". Intenté buscar en línea y parece que no puedo encontrar mucho. Sería muy bueno si pudiéramos desarrollar localmente utilizando solo el sistema de archivos: -/ – Sophistifunk

+0

No tengo un enlace, pero imagino que se ejecuta accidentalmente una página web local maliciosa que podría acceder a cualquier archivo en su sistema - léalo, publíquelo a un servidor arbitrario, incluso puede invocar ciertos comandos. En general, una mala idea. – nrabinowitz

5

Chrome puede usar el trabajador localmente sin el --allow-file-access-from-files. El trabajador debe cargarse como una burbuja.

Ejemplo:

<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> 

Los worker_lib2.js archivo:

function hello(msg) { 
    return 'Hello... ' + msg; 
} 
Cuestiones relacionadas