Chrome non può caricare il web worker


109

Sto lavorando a un progetto che utilizza un web worker.

Nella mia sezione di testa ho questo codice:

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

Funziona bene in Safari, ma Chrome segnala il seguente errore:

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

Perché funziona perfettamente in Safari ma non in Chrome? Come lo risolvo?

Grazie.


1
Stai lavorando fuori dal protocollo file? Se si imposta il flag di accesso e vedere se funziona: stackoverflow.com/questions/18586921/...
epascarello

1
Sì, il percorso per il lavoratore web è questo: file:///E:/programming/web/project/worker.js. Il percorso per il progetto principale è questo: file:///E:/programming/web/project/index.html.
Progo

Risposte:


84

Chrome non ti consente di caricare i web worker durante l'esecuzione di script da un file locale.


6
Da questa risposta , Loading a local file, even with a relative URL, is the same as loading a file with the file: protocol.- e non è bello per le pagine web poter accedere al tuo file system per capriccio.
ChaseMoskal

41
-1 firsfox ti consentirà di farlo ovviamente, a condizione che tu stia utilizzando anche un file come origine (ad esempio, stai visualizzando il file locale nel browser). È solo il cromo che è rotto.
Tomáš Zato - Ripristina Monica il

3
Firefox funziona ancora (sì dal file: //), Chrome in questo caso non funziona.
Evil

55

Uso una soluzione alternativa. Chrome si blocca Workerma non <script>. Quindi il modo migliore per realizzare una soluzione universale è questo:

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

Quindi lo colleghi normalmente <script src="...". E una volta definita la funzione, usi questo abominio di codice:

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

Questa soluzione è buona. perché in questo mondo niente è perfetto? Ogni software sta agitando gli utenti con bug, difetti, comportamenti infantili, ecc. Firefox è anche arrogante in quanto si rifiuta di supportare la proprietà css "clip-path".
Ĭsααc t ի ε βöss

Non sono uno sviluppatore js e non capisco il punto dell'uso del tag script qui. E qual è la finestra! = Autocontrollo? Qualcuno può spiegare questa sequenza di caricamento? Grazie.
Sharun

I tag script verranno caricati da Google Chrome se si trovano nella stessa directory di HTML. window!=seldcontrolla se il codice è in esecuzione nel web worker. Questo rende questo codice portabile nel caso in cui carichi il file javascript direttamente in altri contesti.
Tomáš Zato - Ripristina Monica il

1
@ treeseal7 Il codice che dovrebbe essere eseguito nel contesto del web worker.
Tomáš Zato - Ripristina Monica il

2
Dovrei notare che non puoi usare importScript da un worker scritto in questo modo. Almeno, non senza un'ulteriore soluzione alternativa. Quindi avrai bisogno di più manomissioni per un lavoratore con più file.
SlugFiller

41

Il problema è stato adeguatamente spiegato da Noble Chicken, ma ho una soluzione più generale. Invece di installare wamp o xamp, con python puoi navigare nella cartella in cui è ospitato il tuo progetto e digitare:python -m http.server

Solo questo e avrai un server in esecuzione su quella cartella, raggiungibile da localhost.


13
Probabilmente i Mac dovranno andare con python -m SimpleHTTPServer 8000come vengono caricati con <Python 3 (solo per salvare un'altra ricerca su Google: D)
siege_Perilous

3
è anche possibile installare il modulo del nodo del server http, quindi accedere alla cartella desiderata dal terminale ed eseguire "http-server -p 3000".
Huan Zhang

vale la pena menzionare questo script "python -m http.server" necessita di Python 3.
milesma

Prova anchephp -S localhost:8000
William Entriken

29

Puoi anche utilizzare il flag --allow-file-access-from-files quando avvii Chrome.

Esempio per MacOsX:

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

Altre informazioni: impostazioni del Web worker per Chrome


Nella finestra di comando di Windows vai a: "C: \ Users \ NAME \ AppData \ Local \ Google \ Chrome SxS \ Application", quindi esegui chrome.exe --allow-file-access-from-files, quindi copia il percorso del file locale es. c: \ temp \ myWeb \ index.html e incolla nell'URL del browser aperto, fatto.
milesma

4
È inoltre possibile creare una scorciatoia e passare la bandiera nel percorso di destinazione.
Stephan

1
Oh, e dalla domanda collegata, ricordati di chiudere tutte le finestre di Chrome prima di avviare con la bandiera.
Stephan

Sì, un'altra opzione può anche essere quella di codificare un'estensione di Chrome con le autorizzazioni appropriate nel file manifest: "permissions": ["file: // * / *"], come in stackoverflow.com/questions/19493020/…
Mickaël

Nota: "Devi chiudere tutte le finestre di Chrome prima di aprirlo con il --allow-file-access-from-filesflag attivato." come indicato sul stackoverflow.com/a/21771754/325418
nonopolarity

15

È a causa delle restrizioni di sicurezza. Devi usare http://o https://protocollo invece di file:///.

Se hai installato NodeJS, puoi semplicemente fare quanto segue. - Nota che questa è una delle tante opzioni disponibili

Installa il server web locale

$ npm install -g local-web-server

Ora puoi usarlo in qualsiasi cartella attraverso la quale desideri accedere ai contenuti http.

$ ws

Vai a http://localhost:8000(porta predefinita: 8000)


6

Ho avuto anche lo stesso problema del tuo post. La soluzione è che devi eseguirlo con localhost (wamp o xamp). Sarà fatto.


Wow, non l'avrei mai trovato - grazie! (Spero che i ringraziamenti siano consentiti nei commenti)
dcromley

4

Un'altra soluzione alternativa è utilizzare il server web di Google per l' estensione Chrome . Scegli la tua directory di lavoro e avvia il server, Fatto!



3

Chromecaricare il file ma non è possibile eseguirlo. Usa Firefox. Per me sta funzionando.


1
Per spiegare il mio voto negativo: potrebbe essere meglio iniziare con un commento, magari chiedendo di più sui requisiti di supporto del browser, piuttosto che essere presentato come risposta. Sembra molto probabile che non sia una risposta, dato ciò che l'utente ha già detto sul supporto cross-browser.
Thomas Poole

Se hai letto attentamente la domanda, sono sicuro che non voterai per difetto come tre prima di votare! L'utente sta dicendo che Chrome non può caricare il worker. No, Chrome può caricare il worker ma non eseguirlo. I motivi per cui l'ho messo come risposta è che prima la domanda è stata posta un anno fa e la seconda molte risposte dicono che Firefox non sta eseguendo il worker, cosa che non posso commentare tutte. Sto solo spiegando ma hai il diritto di votare verso il basso o votare verso l'alto.
Hocine Ben

3

Un modo semplice per creare un server http locale in Chrome è questa app:

Server Web per Chrome

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

Descrizione:

Un server web per Chrome, serve pagine web da una cartella locale sulla rete, utilizzando HTTP. Funziona offline. Il server Web per Chrome è un server HTTP open source (MIT) per Chrome.

Funziona ovunque tu abbia installato Chrome, quindi puoi portarlo ovunque. Funziona anche su Chromebook ARM.

Ora ha la possibilità di ascoltare sulla rete locale, in modo che altri computer possano accedere ai tuoi file. Inoltre, può provare a ottenere un indirizzo Internet.

Molte persone lo usano per eseguire lo sviluppo web di base su un Chromebook. È anche utile per condividere file su una rete locale tra computer o anche su Internet.

Una volta installato, vai a http://127.0.0.1:8887

E non è sicuro come flag --allow-file-access-from-files


È fantastico! Ora posso eseguire la mia app reactJS con i web worker dal file system locale. Non può essere molto più facile!
Json

3

Questo è ispirato dalla risposta di Thomas sopra. Ma con un avvertimento che volevo distribuire solo l'HTML, quindi ho convertito manualmente js in dataURL . e abilitando la casella di controllo URL dati in essa.

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


2

Con Python 2.x più ampiamente distribuito rispetto a Python 3.x, qualcosa di simile python -m SimpleHTTPServer 8000è più generalmente applicabile, e non solo per Mac OS X. L'ho trovato necessario per l'uso sotto Cygwin, per esempio.

Con quello a posto, questo esempio ha funzionato come un campione.


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

Come accennato chrome non lo supporta. Mi piace definire i miei lavoratori nello stesso file. Questa è una soluzione alternativa che aumenterà il numero trovato in innerHTML dell'elemento the id=numogni 500 ms.


1

Probabilmente una ragione è che chrome non ti consente di caricare i web worker durante l'esecuzione di script da un file locale. E provo a eseguire il codice sul mio Firefox, non posso neanche.


I web file://worker funzionano bene in Firefox 51.0.1
bryc

-6

Sì, non funzionerà in chorome se stai caricando un file locale. Ma funzionerà bene nel browser Firefox. E devi aggiungere sotto il codice nel file HTML.

<head>
    <meta charset="UTF-8" />
</head>
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.