Chrome nie może załadować programu web Worker

109

Pracuję nad projektem, w którym jest używany pracownik sieciowy.

W mojej sekcji head mam ten kod:

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

Działa to dobrze w Safari, ale Chrome zgłasza następujący błąd:

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

Dlaczego to działa doskonale w Safari, ale nie w Chrome? Jak to naprawić?

Dziękuję Ci.

Progo
źródło
1
Czy pracujesz nad protokołem plików? Jeśli ustawisz flagę dostępu i zobaczysz, czy działa: stackoverflow.com/questions/18586921/ ...
epascarello
1
Tak, ścieżka dla pracownika internetowej to: file:///E:/programming/web/project/worker.js. Ścieżka do głównego projektu to: file:///E:/programming/web/project/index.html.
Progo
1
Spróbuj tego: stackoverflow.com/questions/18586921/…
epascarello

Odpowiedzi:

84

Chrome nie pozwala ładować pracowników sieci podczas uruchamiania skryptów z pliku lokalnego.

Kurczak Nobla
źródło
6
Z tej odpowiedziLoading a local file, even with a relative URL, is the same as loading a file with the file: protocol. wynika , - i nie jest fajnie, aby strony internetowe mogły po prostu uzyskać dostęp do systemu plików dla kaprysu.
ChaseMoskal,
41
-1 firsfox pozwoli ci to oczywiście zrobić, pod warunkiem, że używasz również pliku jako źródła (np. Przeglądasz plik lokalny w przeglądarce). To tylko chrom, który jest zepsuty.
Tomáš Zato - Przywróć Monikę
3
Firefox nadal działa (tak z pliku: //), Chrome w tym przypadku nie.
Zło
55

Używam obejścia. Chrome blokuje, Workerale nie <script>. Dlatego najlepszym sposobem na stworzenie uniwersalnego rozwiązania jest:

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

Następnie łączysz to w normalny sposób <script src="...". A kiedy funkcja jest zdefiniowana, używasz tej obrzydliwości kodu:

new Worker(URL.createObjectURL(new Blob(["("+worker_function.toString()+")()"], {type: 'text/javascript'})));
Tomáš Zato - Przywróć Monikę
źródło
To dobre rozwiązanie. dlaczego na tym świecie nic nie jest doskonałe? Każde oprogramowanie irytuje użytkowników błędami, błędami, dziecięcymi zachowaniami itp. Firefox jest również arogancki, ponieważ odmawia obsługi właściwości css „clip-path”.
Ĭsααc t ի ε βöss
Nie jestem deweloperem js i nie rozumiem sensu użycia tutaj tagu script. A do czego służy okno! = Samokontrola? Czy ktoś może wyjaśnić tę sekwencję ładowania? Dzięki.
Sharun,
Tagi skryptów zostaną załadowane przez Google Chrome, jeśli znajdują się w tym samym katalogu co HTML. window!=seldsprawdza, czy kod działa w programie Web Worker. To sprawia, że ​​ten kod jest przenośny w przypadku załadowania pliku javascript bezpośrednio w innych kontekstach.
Tomáš Zato - Przywróć Monikę
1
@ treeseal7 Kod, który powinien być wykonywany w kontekście narzędzia WWW.
Tomáš Zato - Przywróć Monikę
2
Powinienem zauważyć, że nie możesz użyć importScriptu od pracownika napisanego w ten sposób. Przynajmniej nie bez dodatkowego obejścia. Będziesz więc potrzebować więcej manipulacji dla pracownika obsługującego wiele plików.
SlugFiller
41

Problem został odpowiednio wyjaśniony przez Noble Chicken, ale mam bardziej ogólne rozwiązanie. Zamiast instalować wamp lub xamp, za pomocą Pythona możesz przejść do folderu, w którym znajduje się twój projekt, i wpisać:python -m http.server

Wystarczy, że będziesz miał działający serwer w tym folderze, dostępny z lokalnego hosta.

Robert Parcus
źródło
13
Komputery Mac prawdopodobnie będą musiały działać, python -m SimpleHTTPServer 8000ponieważ są załadowane <Python 3 (tylko po to, aby zapisać kolejne wyszukiwanie w Google: D)
siege_Perilous,
3
możesz także zainstalować moduł węzła serwera http, a następnie przejść do żądanego folderu z terminala i uruchomić „http-server -p 3000”.
Huan Zhang
warto wspomnieć o tym skrypcie "python -m http.server" potrzebuje Pythona 3.
milesma
Spróbuj takżephp -S localhost:8000
William Entriken,
29

Możesz także użyć flagi --allow-file-access-from-files podczas uruchamiania Chrome.

Przykład dla MacOsX:

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

Więcej informacji: ustawienia pracownika sieci Web dla Chrome

Mickaël
źródło
W oknie poleceń systemu Windows przejdź do: „C: \ Users \ NAME \ AppData \ Local \ Google \ Chrome SxS \ Application”, a następnie uruchom chrome.exe --allow-file-access-from-files, a następnie skopiuj lokalną ścieżkę do pliku np. c: \ temp \ myWeb \ index.html i wklej do adresu URL otwartej przeglądarki, gotowe.
milesma
4
Możesz także utworzyć skrót i przekazać flagę w docelowej ścieżce.
Stephan
1
Aha, i z połączonego pytania pamiętaj, aby zamknąć wszystkie okna Chrome przed uruchomieniem z flagą.
Stephan
Tak, inną opcją może być również zakodowanie rozszerzenia Chrome z odpowiednimi uprawnieniami w jego manifeście: "permissions": ["file: // * / *"], jak na stackoverflow.com/questions/19493020/ ...
Mickaël
Uwaga: „Musisz zamknąć wszystkie okna przeglądarki Chrome, zanim otworzysz ją z --allow-file-access-from-fileswłączoną flagą”. jak podano na stackoverflow.com/a/21771754/325418
nonopolarity
15

Wynika to z ograniczeń bezpieczeństwa. Zamiast tego musisz użyć protokołu http://lub .https://file:///

Jeśli masz zainstalowany NodeJS, możesz po prostu wykonać następujące czynności. - Należy pamiętać, że jest to jedna z wielu dostępnych opcji

Zainstaluj lokalny serwer sieciowy

$ npm install -g local-web-server

Teraz możesz go używać w dowolnym folderze, przez który chcesz uzyskać dostęp do zawartości http.

$ ws

Przejdź do http://localhost:8000(domyślny port: 8000)

Bezpieczniejszy Hussain
źródło
6

Miałem ten sam problem co twój post. Rozwiązaniem jest to, że musisz uruchomić go z localhost (wamp lub xamp). To się skończy.

Thara
źródło
Wow, nigdy bym tego nie znalazł - dzięki! (Mam nadzieję, że podziękowania są dozwolone w komentarzach)
dcromley
3

potrzebujesz serwera WWW do żądania z protokołu HTTP Zamiast lokalnego pliku i działa poprawnie :)

Alireza Alallah
źródło
1
Nie, nie masz. Musisz zignorować przeglądarki, które nie są zgodne ze standardami sieciowymi tylko dlatego, że są popularne.
Tomáš Zato - Przywróć Monikę
3

Chromezaładować plik, ale nie można go uruchomić. Użyj Firefox. To działa na mnie.

Hocine Ben
źródło
1
Aby wyjaśnić mój głos negatywny: lepiej byłoby zacząć od komentarza, być może zapytać się więcej o wymagania dotyczące obsługi przeglądarek, niż być przesłanym jako odpowiedź. Wydaje się, że nie jest to odpowiedź, biorąc pod uwagę to, co użytkownik już powiedział o obsłudze różnych przeglądarek.
Thomas Poole
Jeśli uważnie przeczytałeś pytanie, jestem pewien, że nie odrzucisz odpowiedzi jako trzech, zanim zagłosujesz na nią! Użytkownik mówi, że Chrome nie może załadować pracownika. Nie, Chrome może załadować pracownika, ale nie może go uruchomić. Powody, dla których umieściłem to jako odpowiedź, są następujące: po pierwsze pytanie padło rok temu, a po drugie wiele odpowiedzi mówi, że Firefox nie obsługuje pracownika, którego nie mogę wszystkich skomentować. Tylko wyjaśniam, ale masz prawo głosować przeciw lub za.
Hocine Ben
3

Prostym sposobem na utworzenie lokalnego serwera HTTP w Chrome jest ta aplikacja:

Serwer sieciowy dla Chrome

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

Opis:

Serwer sieciowy dla przeglądarki Chrome udostępnia strony internetowe z lokalnego folderu w sieci przy użyciu protokołu HTTP. Działa w trybie offline. Serwer internetowy dla przeglądarki Chrome to serwer HTTP typu open source (MIT) dla przeglądarki Chrome.

Działa wszędzie, gdzie masz zainstalowany Chrome, więc możesz go zabrać wszędzie. Działa nawet na Chromebookach ARM.

Ma teraz opcję nasłuchiwania w sieci lokalnej, dzięki czemu inne komputery mogą uzyskać dostęp do plików. Dodatkowo może spróbować uzyskać adres internetowy.

Wiele osób używa tego do podstawowego tworzenia stron internetowych na Chromebooku. Jest również przydatny do udostępniania plików w sieci lokalnej między komputerami, a nawet w Internecie.

Po zainstalowaniu przejdź do http://127.0.0.1:8887

I nie jest niezabezpieczona jako flaga --allow-file-access-from-files

A. Denis
źródło
To jest niesamowite! Mogę teraz uruchamiać moją aplikację ReactJS z pracownikami sieciowymi z lokalnego systemu plików. Nie może być dużo łatwiej!
Json
3

Inspiruje to powyższa odpowiedź Thomasa. Ale z jednym zastrzeżeniem, że chciałem rozprowadzać tylko HTML, więc ręcznie przekonwertowałem js na dataURL . i zaznaczając w nim pole wyboru adresu URL danych.

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

goutham
źródło
2

Ponieważ Python 2.x jest szerzej wdrażany niż Python 3.x, coś podobnego python -m SimpleHTTPServer 8000ma szersze zastosowanie, i to nie tylko dla Mac OS X. Uważam, że jest to konieczne do użycia na przykład pod Cygwin.

Mając to na miejscu, ten przykład działał jak mistrz.

salfter
źródło
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;
}

Jak wspomniano, chrome go nie obsługuje. Lubię definiować moich pracowników w tym samym pliku. Jest to działające obejście, które będzie zwiększać liczbę znajdującą się w innerHTML elementu the id=numco 500 ms.

Dominik Kolesar
źródło
1

Prawdopodobnie powodem jest to, że Chrome nie pozwala ładować pracowników sieci podczas uruchamiania skryptów z pliku lokalnego. I próbuję uruchomić kod na moim firefoxie, też nie mogę.

Eric Chang
źródło
Pracownicy file://sieciowi działają dobrze w przeglądarce Firefox 51.0.1
bryc
-6

Tak, nie będzie działać w chorome, jeśli ładujesz plik lokalny. Ale będzie działać dobrze w przeglądarce Firefox. I musisz dodać poniższy kod w pliku HTML.

<head>
    <meta charset="UTF-8" />
</head>
anand vishwakarma
źródło