2011-07-25 4 views
8

Quand j'ai essayé de jouer avec les travailleurs fonctionnalité Web en HTML5, mon Firefox fonctionne heureusement, mais le chrome se plaint que:HTML5 Web Workers travaillent dans Firefox 4, mais pas dans 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); 

ce que je peux faire pour cela fonctionne en chrome?

BTW, quand j'essayé l'échantillon à http://playground.html5rocks.com/#inline_workers et cela fonctionne en chrome temps, mais Firefox se plaint que

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

+1

Avez-vous affiché le bon code pour worker.js? Il semble que vous ayez renvoyé worker.html par erreur. – nrabinowitz

+0

Oui, vous avez raison. Ma faute. J'ai collé le worker.js maintenant. – janetsmith

Répondre

6

Je devine que vous essayez de l'exécuter sur votre machine locale, pas un serveur web. Les travailleurs sont limités par le Same Origin Policy, mais comme les notes de page Wikipédia, liés

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

Chargement d'un fichier local, même avec une URL relative, est le même que le chargement d'un fichier avec le protocole file:. Donc, je suppose que le problème est que vous essayez de charger worker.js comme un fichier local - Chrome n'aime pas cela (pour certaines raisons de sécurité), mais vous pouvez forcer le problème en démarrant Chrome comme ceci: chrome.exe --allow-file-access-from-files

Vous pouvez également essayer de traiter votre script sur un serveur Web local ou distant et voir si cela résout le problème. (Si vous avez installé Python, vous pouvez aller dans le répertoire en question et lancer python -m SimpleHTTPServer 8000, puis aller à http://localhost:8000/ dans votre navigateur).

+0

J'ai essayé votre suggestion avec Tomcat 7, ça marche parfaitement! – janetsmith

+0

Je ne pense pas que vous pourriez mettre un lien vers ces "bonnes raisons de sécurité"? J'ai essayé de chercher en ligne et n'arrive pas à trouver beaucoup. Ce serait vraiment bien si nous pouvions développer localement en utilisant seulement le système de fichiers: -/ – Sophistifunk

+0

Je n'ai pas de lien, mais j'imagine que je cours accidentellement une page web locale malveillante qui pourrait accéder à n'importe quel fichier sur votre système. à un serveur arbitraire, potentiellement même invoquer certaines commandes. Généralement une mauvaise idée. – nrabinowitz

5

Chrome peut utiliser un opérateur localement sans le --allow-file-access-from-files. Le travailleur doit être chargé comme un blob.

Exemple:

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

Le fichier worker_lib2.js:

function hello(msg) { 
    return 'Hello... ' + msg; 
} 
Questions connexes