Chrome не может загрузить веб-воркера


110

Я работаю над проектом, в котором используется веб-воркер.

В моем разделе головы у меня есть этот код:

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

Это отлично работает в Safari, но Chrome сообщает о следующей ошибке:

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

Почему это отлично работает в Safari, но не в Chrome? Как это исправить?

Спасибо.


1
Вы работаете с файловым протоколом? Если вы установили флаг доступа и посмотрите, работает ли он: stackoverflow.com/questions/18586921/…
epascarello

1
Да, путь для веб - работника заключается в следующем: file:///E:/programming/web/project/worker.js. Путь для основного проекта заключается в следующем: file:///E:/programming/web/project/index.html.
Progo

1
Попробуйте это: stackoverflow.com/questions/18586921/…
epascarello

Ответы:


85

Chrome не позволяет загружать веб-воркеров при запуске скриптов из локального файла.


6
Из этого ответа , Loading a local file, even with a relative URL, is the same as loading a file with the file: protocol.- и это не круто для веб - страниц , чтобы быть в состоянии только доступа файловой системы по наитию.
ChaseMoskal

41
-1 firsfox, конечно, позволит вам это сделать, если вы также используете файл в качестве источника (например, вы просматриваете локальный файл в браузере). Это просто хром сломан.
Томаш Зато - Восстановите Монику

3
Firefox по-прежнему работает (да, из file: //), Chrome в этом случае не работает.
Evil

55

Я использую обходной путь. Хром блокирует, Workerно нет <script>. Следовательно, лучший способ сделать универсальное решение - это:

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

Затем вы связываете его как обычно <script src="...". И как только функция определена, вы используете эту мерзость кода:

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

Это хорошее решение. почему в этом мире нет ничего идеального? Каждое программное обеспечение волнует пользователей ошибками, недоработками, детским поведением и т. Д. Firefox также высокомерен, поскольку отказывается поддерживать свойство css "clip-path".
Ĭsααc t ի ε βöss

Я не являюсь разработчиком js и не понимаю, как использовать здесь тег скрипта. А что такое окно! = Самопроверка? Может кто-нибудь объяснить эту последовательность загрузки? Спасибо.
Шарун

Теги скрипта будут загружены google chrome, если они находятся в том же каталоге, что и HTML. window!=seldпроверяет, работает ли код в веб-воркере. Это делает этот код переносимым, если вы загружаете файл javascript непосредственно в другом контексте.
Томаш Зато - Восстановить Монику

1
@ treeseal7 Код, который должен выполняться в контексте веб-воркера.
Томаш Зато - Восстановите Монику

2
Я должен отметить, что вы не можете использовать importScript из написанного таким образом воркера. По крайней мере, не без дополнительного обходного пути. Так что вам понадобится больше вмешательств для многофайлового работника.
SlugFiller

41

Проблема была правильно объяснена Noble Chicken, но у меня есть более общее решение. Вместо установки wamp или xamp с помощью python вы можете перейти к папке, в которой размещен ваш проект, и ввести:python -m http.server

Только это, и у вас будет работающий сервер в этой папке, доступный с localhost.


13
Mac, вероятно, придется использовать, python -m SimpleHTTPServer 8000поскольку они загружены с <Python 3 (просто чтобы сохранить еще один поиск в Google: D)
siege_Perilous

3
вы также можете установить модуль узла http-server, а затем перейти в нужную папку с терминала и запустить http-server -p 3000.
Хуан Чжан

Стоит упомянуть, что этот скрипт "python -m http.server" требует Python 3.
milesma

Также попробуйтеphp -S localhost:8000
Уильям Энтрикен 01

29

Вы также можете использовать флаг --allow-file-access-from-files при запуске Chrome.

Пример для MacOsX:

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

Дополнительная информация: настройки веб-воркера для Chrome


В командном окне Windows перейдите к: «C: \ Users \ NAME \ AppData \ Local \ Google \ Chrome SxS \ Application», затем запустите chrome.exe --allow-file-access-from-files, затем скопируйте путь к локальному файлу. например, c: \ temp \ myWeb \ index.html и вставьте в URL-адрес открытого браузера, готово.
milema

4
Вы также можете создать ярлык и передать флаг в целевом пути.
Стефан

1
О, и из связанного вопроса не забудьте закрыть все окна Chrome перед запуском с флагом.
Стефан

Да, другой вариант также может заключаться в кодировании расширения Chrome с правильным разрешением в его манифесте: "permissions": ["file: // * / *"], как в stackoverflow.com/questions/19493020/…
Микаэль

Примечание: «Вы должны закрыть все окна Chrome, прежде чем открывать его с установленным --allow-file-access-from-filesфлажком». как указано на stackoverflow.com/a/21771754/325418
неполярность

15

Это из-за ограничений безопасности. Вам нужно использовать http://или https://протокол вместо file:///.

Если у вас установлен NodeJS, вы можете просто сделать следующее. - Обратите внимание, что это один из многих доступных вариантов

Установить локальный веб-сервер

$ npm install -g local-web-server

Теперь вы можете использовать его в любой папке, через которую хотите получить доступ к содержимому http.

$ ws

Перейдите к http://localhost:8000(порт по умолчанию: 8000)


6

У меня была та же проблема, что и у вашего сообщения. Решение в том, что вам нужно запустить его с помощью localhost (wamp или xamp). Будет сделано.


Вау, я бы никогда этого не нашел - спасибо! (Я надеюсь, что благодарности разрешены в комментариях)
dcromley


3

вам нужен веб-сервер для запроса по протоколу HTTP вместо локального файла и работает правильно :)


1
Нет, не знаешь. Вам нужно игнорировать браузеры, которые не соответствуют веб-стандартам, только потому, что они широко распространены.
Томаш Зато - Восстановите Монику

3

Chromeзагрузить файл, но не может его запустить. Используйте Firefox. У меня это работает.


1
Чтобы объяснить мое отрицательное голосование: лучше начать с комментария, возможно, узнать больше о требованиях к поддержке браузера, чем быть отправленным в качестве ответа. Скорее всего, это не ответ, учитывая то, что пользователь уже сказал о кроссбраузерной поддержке.
Thomas Poole

Если вы внимательно прочитали вопрос, я уверен, что вы не проголосуете за ответ как три, прежде чем проголосуете за него! Пользователь говорит, что Chrome не может загрузить воркер. Нет, Chrome может загрузить воркер, но не может его запустить. Причины, по которым я поставил это как ответ, - это, во-первых, вопрос, заданный год назад, а во-вторых, многие ответы говорят, что Firefox не запускает воркер, и я не могу прокомментировать их все. Я просто объясняю, но у вас есть право голосовать против или за.
Hocine Ben

3

Простой способ сделать локальный http-сервер в Chrome - это приложение:

Веб-сервер для Chrome

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

Описание:

Веб-сервер для Chrome обслуживает веб-страницы из локальной папки по сети с помощью HTTP. Работает офлайн. Веб-сервер для Chrome - это HTTP-сервер с открытым исходным кодом (MIT) для Chrome.

Он работает везде, где установлен Chrome, поэтому вы можете брать его с собой куда угодно. Он работает даже на хромбуках ARM.

Теперь у него есть возможность слушать в локальной сети, чтобы другие компьютеры могли получить доступ к вашим файлам. Кроме того, он может попытаться получить интернет-адрес.

Многие люди используют это для базовой веб-разработки на Chromebook. Это также удобно для обмена файлами по локальной сети между компьютерами или даже в Интернете.

После установки перейдите по адресу http://127.0.0.1:8887.

И это небезопасно, поскольку флаг --allow-file-access-from-files


Это потрясающе! Теперь я могу запустить приложение responseJS с веб-рабочими из локальной файловой системы. Нет ничего проще!
Json

3

Это вдохновлено ответом Томаса выше. Но с одной оговоркой, что я хотел распространять только HTML, поэтому я вручную преобразовал js в dataURL . и установите в нем флажок URL-адреса данных.

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


2

Поскольку Python 2.x используется более широко, чем Python 3.x, что-то вроде python -m SimpleHTTPServer 8000 более широко применимо, и не только для Mac OS X. Я счел это необходимым для использования, например, в Cygwin.

С учетом этого, этот пример работал как чемпион.


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

Как уже упоминалось, хром не поддерживает его. Мне нравится определять своих воркеров в одном файле. Это рабочий обходной путь, который будет увеличивать число в innerHTML элемента id=numкаждые 500 мс.


1

Вероятно, причина в том, что Chrome не позволяет загружать веб-воркеров при запуске скриптов из локального файла. И я пытаюсь запустить код на моем firefox, тоже не могу.


Веб- file://воркеры отлично работают в Firefox 51.0.1
bryc,

-6

Да, это не будет работать в chorome, если вы загружаете локальный файл. Но в браузере firefox он будет работать нормально. И вы должны добавить код ниже в файл HTML.

<head>
    <meta charset="UTF-8" />
</head>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.