Chrome não pode carregar web worker

109

Estou trabalhando em um projeto que usa um trabalhador da web.

Na minha seção principal, tenho este código:

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

Isso funciona bem no Safari, mas o Chrome relata o seguinte erro:

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

Por que isso funciona perfeitamente no Safari, mas não no Chrome? Como faço para corrigir isso?

Obrigado.

Progo
fonte
1
Você está trabalhando fora do protocolo de arquivo? Se você configurou o sinalizador de acesso e veja se funciona: stackoverflow.com/questions/18586921/…
epascarello
1
Sim, o caminho para o trabalhador web é o seguinte: file:///E:/programming/web/project/worker.js. O caminho para o projeto principal é esta: file:///E:/programming/web/project/index.html.
Progo
1
Tente isto: stackoverflow.com/questions/18586921/…
epascarello

Respostas:

84

O Chrome não permite que você carregue web workers ao executar scripts de um arquivo local.

Frango Nobel
fonte
6
Com essa resposta , Loading a local file, even with a relative URL, is the same as loading a file with the file: protocol.- e não é legal para as páginas da web acessarem seu sistema de arquivos por capricho.
ChaseMoskal
41
-1 firsfox permitirá que você faça isso, é claro, desde que você também esteja usando o arquivo como origem (por exemplo, você está visualizando o arquivo local no navegador). É apenas o cromo que está quebrado.
Tomáš Zato - Reintegrar Monica em
3
O Firefox ainda funciona (sim, do arquivo: //), o Chrome não neste caso.
Mal
55

Eu uso uma solução alternativa. O Chrome bloqueia, Workermas não <script>. Portanto, a melhor maneira de fazer uma solução universal é esta:

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

Você então o vincula normalmente <script src="...". E uma vez que a função é definida, você usa esta abominação de um código:

new Worker(URL.createObjectURL(new Blob(["("+worker_function.toString()+")()"], {type: 'text/javascript'})));
Tomáš Zato - Reintegrar Monica
fonte
Essa solução é boa. porque neste mundo nada é perfeito? Todo software está agitando os usuários com bugs, falhas, comportamentos infantis etc. O Firefox também é arrogante, pois se recusa a suportar a propriedade css "clip-path".
Ĭsααc t ի ε βöss
Eu não sou um js dev e não entendo o ponto do tag script usado aqui. E o que é a janela! = Autoverificação? Alguém pode explicar essa sequência de carregamento? THX.
Sharun,
As tags de script serão carregadas pelo google chrome se estiverem no mesmo diretório do HTML. window!=seldverifica se o código está sendo executado no web worker. Isso torna este código portátil no caso de você carregar o arquivo javascript diretamente em outros contextos.
Tomáš Zato - Reintegrar Monica em
1
@ treeseal7 O código que deve ser executado no contexto do web worker.
Tomáš Zato - Reintegrar Monica em
2
Devo observar que você não pode usar importScript de um trabalhador escrito assim. Pelo menos, não sem uma solução alternativa adicional. Portanto, você precisará de mais adulteração para um trabalhador de vários arquivos.
SlugFiller de
41

O problema foi devidamente explicado pela Noble Chicken, mas tenho uma solução mais geral para ele. Em vez de instalar o wamp ou o xamp, com o python você pode navegar até a pasta em que seu projeto está hospedado e digitar:python -m http.server

Apenas isso e você terá um servidor em execução nessa pasta, acessível a partir de localhost.

Robert Parcus
fonte
13
Provavelmente, os Macs precisarão ser python -m SimpleHTTPServer 8000carregados com o <Python 3 (apenas para salvar outra pesquisa do Google: D)
siege_Perilous
3
você também pode instalar o módulo de nó do servidor http e navegar até a pasta desejada no terminal e executar 'http-server -p 3000'.
Huan Zhang
vale a pena mencionar este script "python -m http.server" precisa do Python 3.
milesma
Experimente tambémphp -S localhost:8000
William Entriken
29

Você também pode usar o sinalizador --allow-file-access-from-files ao iniciar o Chrome.

Exemplo para MacOsX:

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

Mais informações: configurações do Web worker para Chrome

Mickaël
fonte
Na janela de comando do Windows, navegue até: "C: \ Users \ NAME \ AppData \ Local \ Google \ Chrome SxS \ Application", execute chrome.exe --allow-file-access-from-files e copie o caminho do arquivo local por exemplo, c: \ temp \ myWeb \ index.html e cole na url do navegador aberto, pronto.
milesma de
4
Você também pode criar um atalho e passar a bandeira no caminho de destino.
Stephan,
1
Ah, e pela pergunta vinculada, lembre-se de fechar todas as janelas do Chrome antes de lançar com a bandeira.
Stephan,
Sim, uma outra opção também pode ser codificar uma extensão do Chrome com a permissão correta em seu manifesto: "permissions": ["file: // * / *"], como em stackoverflow.com/questions/19493020/…
Mickaël
Nota: "Você tem que fechar todas as janelas do Chrome antes de abri-lo com a --allow-file-access-from-filesbandeira ativada." conforme indicado em stackoverflow.com/a/21771754/325418
nonopolarity
15

É por causa das restrições de segurança. Você precisa usar o protocolo http://ou em https://vez de file:///.

Se você tiver o NodeJS instalado, pode simplesmente fazer o seguinte. - Observe que esta é uma das muitas opções disponíveis

Instalar servidor web local

$ npm install -g local-web-server

Agora você pode usá-lo em qualquer pasta através da qual deseja acessar o conteúdo http.

$ ws

Navegue até http://localhost:8000(porta padrão: 8000)

Safeer Hussain
fonte
6

Eu tive o mesmo problema que sua postagem também. A solução é executá-lo com localhost (wamp ou xamp). Vai ser feito.

Thara
fonte
Uau, eu nunca teria encontrado isso - obrigado! (Espero que os agradecimentos sejam permitidos nos comentários)
dcromley
4

Outra solução alternativa é usar o servidor da web do Google para a extensão do Chrome . Escolha seu diretório de trabalho e inicie o servidor, Pronto!

Yubo
fonte
3

você precisa de um servidor web para solicitação de protocolo HTTP em vez de arquivo local e funcione corretamente :)

Alireza Alallah
fonte
1
Não, você não precisa. Você precisa ignorar os navegadores que não seguem os padrões da web apenas porque são convencionais.
Tomáš Zato - Reintegrar Monica em
3

Chromecarregar o arquivo, mas não pode executá-lo. Use Firefox. Está funcionando para mim.

Hocine Ben
fonte
1
Para explicar meu voto negativo: Seria melhor começar com um comentário, talvez perguntando mais sobre os requisitos de suporte do navegador, em vez de ser enviado como resposta. Parece muito provável que não seja uma resposta, dado o que o usuário já disse sobre o suporte cross-browser.
Thomas Poole
Se você leu a pergunta com atenção, tenho certeza de que não votará contra a resposta como três antes de votar a favor! O usuário está dizendo que o Chrome não pode carregar o trabalhador. Não, o Chrome pode carregar o trabalhador, mas não pode executá-lo. As razões pelas quais eu coloquei isso como uma resposta é que primeiro a pergunta foi feita um ano atrás e a segunda muitas respostas estão dizendo que o Firefox não está executando o trabalhador, que não posso comentar todos eles. Estou apenas explicando, mas você tem o direito de votar contra ou votar.
Hocine Ben
3

Uma maneira fácil de criar um servidor http local no Chrome é este aplicativo:

Servidor Web para Chrome

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

Descrição:

Um servidor da web para Chrome, serve páginas da web de uma pasta local na rede, usando HTTP. Funciona offline. O Web Server for Chrome é um servidor HTTP de código aberto (MIT) para o Chrome.

Ele roda em qualquer lugar que você tenha o Chrome instalado, então você pode levá-lo para qualquer lugar. Ele funciona até mesmo em Chromebooks ARM.

Agora, ele tem a opção de ouvir na rede local, para que outros computadores possam acessar seus arquivos. Além disso, ele pode tentar obter um endereço de Internet.

Muitas pessoas usam isso para fazer o desenvolvimento básico da web em um Chromebook. Também é útil para compartilhar arquivos em uma rede local entre computadores ou mesmo na Internet.

Depois de instalá-lo, navegue para http://127.0.0.1:8887

E não é inseguro como sinalizador --allow-file-access-from-files

A. Denis
fonte
Isso é incrível! Agora posso executar meu aplicativo reactJS com web workers do sistema de arquivos local. Não pode ser muito mais fácil!
Json
3

Isso é inspirado na resposta de Thomas acima. Mas com uma ressalva de que eu queria distribuir apenas o HTML, então converti manualmente o js em dataURL . e habilitando a caixa de seleção URL de dados nele.

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

Goutham
fonte
2

Com o Python 2.x sendo implementado de forma mais ampla do que o Python 3.x, algo como python -m SimpleHTTPServer 8000é mais geralmente aplicável, e não apenas para Mac OS X. Eu achei necessário para uso no Cygwin, por exemplo.

Com isso em vigor, este exemplo funcionou como um campeão.

salfter
fonte
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;
}

Como mencionado, o cromo não o suporta. Gosto de definir meus trabalhadores no mesmo arquivo. Esta é uma solução alternativa que aumentará o número encontrado no innerHTML do elemento a id=numcada 500 ms.

Dominik Kolesar
fonte
1

Provavelmente, o cromo não permite que você carregue web workers ao executar scripts de um arquivo local. E tento executar o código no meu firefox, também não consigo.

Eric Chang
fonte
Web Workers funcionando bem file://no Firefox 51.0.1
bryc
-6

Sim, não funcionará em chorome se você estiver carregando um arquivo local. Mas funcionará bem no navegador firefox. E você tem que adicionar o código abaixo no arquivo HTML.

<head>
    <meta charset="UTF-8" />
</head>
anand vishwakarma
fonte