Chrome ne peut pas charger le web worker


109

Je travaille sur un projet qui utilise un web worker.

Dans ma section principale, j'ai ce code:

var worker = new Worker("worker.js");
// More code

Cela fonctionne bien dans Safari, mais Chrome signale l'erreur suivante:

Uncaught SecurityError: Failed to create a worker: script at '(path)/worker.js' cannot be accessed from origin 'null'.

Pourquoi cela fonctionne-t-il parfaitement dans Safari mais pas dans Chrome? Comment puis-je réparer ça?

Je vous remercie.


1
Travaillez-vous sur le protocole de fichier? Si vous définissez l'indicateur d'accès et voyez s'il fonctionne: stackoverflow.com/questions/18586921/…
epascarello

1
Oui, le chemin pour le travailleur Web est la suivante: file:///E:/programming/web/project/worker.js. Le chemin pour le projet principal est la suivante: file:///E:/programming/web/project/index.html.
Progo

Réponses:


84

Chrome ne vous permet pas de charger des collaborateurs Web lors de l'exécution de scripts à partir d'un fichier local.


6
D'après cette réponse , Loading a local file, even with a relative URL, is the same as loading a file with the file: protocol.- et ce n'est pas cool pour les pages Web de pouvoir accéder simplement à votre système de fichiers sur un coup de tête.
ChaseMoskal

41
-1 firsfox vous permettra de le faire bien sûr, à condition que vous utilisiez également le fichier comme origine (par exemple, vous visualisez le fichier local dans le navigateur). C'est juste du chrome qui est cassé.
Tomáš Zato - Réintégrer Monica

3
Firefox fonctionne toujours (oui à partir de file: //), Chrome ne fonctionne pas dans ce cas.
Evil

55

J'utilise une solution de contournement. Chrome bloque Workermais pas <script>. La meilleure façon de créer une solution universelle est donc la suivante:

function worker_function() {
    // all code here
}
// This is in case of normal worker start
// "window" is not defined in web worker
// so if you load this file directly using `new Worker`
// the worker code will still execute properly
if(window!=self)
  worker_function();

Vous le liez ensuite comme d'habitude <script src="...". Et une fois la fonction définie, vous utilisez cette abomination de code:

new Worker(URL.createObjectURL(new Blob(["("+worker_function.toString()+")()"], {type: 'text/javascript'})));

Cette solution est bonne. pourquoi dans ce monde rien n'est parfait? Chaque logiciel agite les utilisateurs avec des bogues, des défauts, des comportements enfantins, etc. Firefox est également arrogant car il refuse de supporter la propriété css "clip-path".
Ĭsααc t ի ε βöss

Je ne suis pas un développeur js et je ne comprends pas l'intérêt de l'utilisation de la balise de script ici. Et quelle est la fenêtre! = Auto-vérification? Quelqu'un peut-il expliquer cette séquence de chargement? THX.
Sharun

Les balises de script seront chargées par google chrome si elles se trouvent dans le même répertoire que HTML. window!=seldvérifie si le code s'exécute dans Web Worker. Cela rend ce code portable au cas où vous chargez le fichier javascript directement dans d'autres contextes.
Tomáš Zato - Réintégrer Monica le

1
@ treeeal7 Le code qui doit s'exécuter dans un contexte de travail Web.
Tomáš Zato - Réintégrer Monica

2
Je dois noter que vous ne pouvez pas utiliser importScript à partir d'un worker écrit comme ceci. Au moins, non sans une solution de contournement supplémentaire. Vous aurez donc besoin de plus de falsification pour un travailleur multi-fichiers.
SlugFiller

41

Le problème a été correctement expliqué par Noble Chicken mais j'ai une solution plus générale pour cela. Au lieu d'installer wamp ou xamp, avec python, vous pouvez accéder au dossier dans lequel votre projet est hébergé et taper:python -m http.server

Juste cela et vous aurez un serveur en cours d'exécution sur ce dossier, accessible à partir de l'hôte local.


13
Les Mac devront probablement aller avec python -m SimpleHTTPServer 8000car ils sont chargés avec <Python 3 (juste pour enregistrer une autre recherche Google: D)
siege_Perilous

3
vous pouvez également installer le module de noeud du serveur http, puis accéder au dossier souhaité à partir du terminal et exécuter «http-server -p 3000».
Huan Zhang

il vaut la peine de mentionner ce script "python -m http.server" besoin de Python 3.
milesma

Essayez aussiphp -S localhost:8000
William Entriken

29

Vous pouvez également utiliser l' indicateur --allow-file-access-from-files lorsque vous lancez Chrome.

Exemple pour MacOsX:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files

Plus d'informations: Paramètres de l'agent Web pour Chrome


Dans la fenêtre de commande Windows, accédez à: "C: \ Users \ NAME \ AppData \ Local \ Google \ Chrome SxS \ Application", puis exécutez chrome.exe --allow-file-access-from-files, puis copiez votre chemin de fichier local par exemple c: \ temp \ myWeb \ index.html et collez-le dans l'url du navigateur ouvert, c'est fait.
milesma

4
Vous pouvez également créer un raccourci et passer l'indicateur dans le chemin cible.
Stephan le

1
Oh, et à partir de la question liée, n'oubliez pas de fermer toutes les fenêtres Chrome avant de lancer avec le drapeau.
Stephan le

Oui, une autre option peut également être de coder une extension Chrome avec la bonne autorisation dans son manifeste: "permissions": ["file: // * / *"], comme dans stackoverflow.com/questions/19493020/…
Mickaël

Remarque: "Vous devez fermer toutes les fenêtres de Chrome avant de l'ouvrir avec l' --allow-file-access-from-filesindicateur activé." comme indiqué sur stackoverflow.com/a/21771754/325418
nonopolarity

15

C'est à cause des restrictions de sécurité. Vous devez utiliser http://ou https://protocole au lieu de file:///.

Si NodeJS est installé, vous pouvez simplement faire ce qui suit. - Notez que c'est l'une des nombreuses options disponibles

Installer le serveur Web local

$ npm install -g local-web-server

Vous pouvez maintenant l'utiliser dans n'importe quel dossier par lequel vous souhaitez accéder au contenu http.

$ ws

Accédez à http://localhost:8000(port par défaut: 8000)


6

J'ai eu le même problème que votre message aussi. La solution est que vous devez l'exécuter avec localhost (wamp ou xamp). Ce sera fait.


Wow, je n'aurais jamais trouvé ça - merci! (J'espère que les remerciements sont autorisés dans les commentaires)
dcromley


3

vous avez besoin d'un serveur Web pour la demande du protocole HTTP au lieu d'un fichier local et fonctionne correctement :)


1
Non tu ne le fais pas. Vous devez ignorer les navigateurs qui ne respectent pas les normes du Web simplement parce qu'ils sont courants.
Tomáš Zato - Réintégrer Monica

3

Chromecharge le fichier mais ne peut pas l'exécuter. Utilisez Firefox. Ça marche pour moi.


1
Pour expliquer mon vote défavorable: il serait peut-être préférable de commencer par un commentaire, peut-être en demandant davantage sur les exigences de prise en charge de leur navigateur, plutôt que d'être soumis comme réponse. Cela ne semble probablement pas une réponse, étant donné ce que l'utilisateur a déjà dit à propos de la prise en charge de plusieurs navigateurs.
Thomas Poole

Si vous avez lu la question attentivement, je suis sûr que vous ne voterez pas contre la réponse à trois avant de voter! L'utilisateur dit que Chrome ne peut pas charger le collaborateur. Non, Chrome peut charger le worker mais ne peut pas l'exécuter. Les raisons pour lesquelles je l'ai mis en réponse est que la première question est posée il y a un an et la seconde, de nombreuses réponses disent que Firefox n'exécute pas le worker, ce que je ne peux pas tous commenter. J'explique juste mais vous avez le droit de voter à la baisse ou à la hausse.
Hocine Ben

3

Un moyen facile de créer un serveur http local dans ChromeCette application est un :

Serveur Web pour Chrome

https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb/related

La description:

Un serveur Web pour Chrome sert des pages Web à partir d'un dossier local sur le réseau, en utilisant HTTP. Fonctionne hors ligne. Web Server for Chrome est un serveur HTTP open source (MIT) pour Chrome.

Il fonctionne partout où Chrome est installé, vous pouvez donc l'emporter n'importe où. Cela fonctionne même sur les Chromebooks ARM.

Il a maintenant la possibilité d'écouter sur le réseau local, afin que d'autres ordinateurs puissent accéder à vos fichiers. De plus, il peut essayer d'obtenir une adresse Internet.

De nombreuses personnes l'utilisent pour faire du développement Web de base sur un Chromebook. Il est également pratique pour partager des fichiers sur un réseau local entre des ordinateurs, ou même sur Internet.

Une fois que vous l'avez installé, accédez à http://127.0.0.1:8887

Et ce n'est pas non plus sécurisé car flag --allow-file-access-from-files


Ceci est incroyable! Je peux maintenant exécuter mon application reactJS avec des travailleurs Web à partir du système de fichiers local. Ça ne peut pas être beaucoup plus facile!
Json

3

Ceci est inspiré par la réponse de Thomas ci-dessus. Mais avec une mise en garde que je voulais distribuer uniquement le HTML, j'ai donc converti manuellement les js en dataURL . et en activant la case à cocher URL des données.

const myWorker = new Worker("data:application/x-javascript;base64,b25tZXNzYW...");


2

Avec Python 2.x étant plus largement déployé que Python 3.x, quelque chose comme python -m SimpleHTTPServer 8000est plus généralement applicable, et pas seulement pour Mac OS X. Je l'ai trouvé nécessaire pour une utilisation sous Cygwin, par exemple.

Avec cela en place, cet exemple a fonctionné comme un champion.


2
function worker_fun(num){
    num ++
    // console.log(num)
    postMessage(num);
    setTimeout(worker_fun.bind(null,num), 500)
}

var w

function startWorker(){
    var blob = new Blob([
        "onmessage = function(e){\
            " + worker_fun.toString() + "\
            worker_fun(e.data.num);}"
    ]);
    var blobURL = window.URL.createObjectURL(blob);
    if (typeof(Worker) != 'undefined'){
        if (typeof(w) == 'undefined'){

            w = new Worker(blobURL);
            w.onmessage = function(event){
                document.getElementById('num').innerHTML = event.data;
            } 
            w.postMessage({
               num:parseInt(document.getElementById('num').innerHTML)})
        }
    }
}


function stopWorker() { 
    w.terminate();
    w = undefined;
}

Comme mentionné, chrome ne le prend pas en charge. J'aime définir mes travailleurs dans le même fichier. Il s'agit d'une solution de contournement qui augmentera le nombre trouvé dans innerHTML de l'élément le id=numtoutes les 500 ms.


1

Une raison probable est que Chrome ne vous permet pas de charger les travailleurs Web lors de l'exécution de scripts à partir d'un fichier local. Et j'essaye d'exécuter le code sur mon firefox, je ne peux pas non plus.


Web Workers fonctionnant file://correctement dans Firefox 51.0.1
bryc

-6

Oui, cela ne fonctionnera pas dans chorome si vous chargez un fichier local. Mais cela fonctionnera bien dans le navigateur Firefox. Et vous devez ajouter le code ci-dessous dans le fichier HTML.

<head>
    <meta charset="UTF-8" />
</head>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.