Chrome не может загрузить веб-работника
Я работаю над проектом, который использует веб-работника.
В моем разделе головы у меня есть этот код:
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? Как это исправить?
Спасибо.
16 ответов
Chrome не позволяет загружать веб-работников при запуске сценариев из локального файла.
Я использую обходной путь. Хромированные блоки 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'})));
Noble Chicken правильно объяснил проблему, но у меня есть более общее решение. Вместо установки wamp или xamp, с помощью python вы можете перейти к папке, в которой находится ваш проект, и набрать: python -m http.server
Просто у вас будет запущенный сервер в этой папке, доступный из localhost.
Вы также можете использовать флаг --allow-file-access-from-files при запуске Chrome.
Пример для MacOsX:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files
Дополнительная информация: настройки веб-рабочего для Chrome
Это из-за ограничений безопасности. Вам нужно использовать http://
или же https://
протокол вместо file:///
,
Если у вас установлен NodeJS, вы можете просто сделать следующее. - Обратите внимание, что это один из многих доступных вариантов
Установить локальный веб-сервер
$ npm install -g local-web-server
Теперь вы можете использовать его в любой папке, к которой вы хотите получить доступ через http
,
$ ws
Перейдите к http://localhost:8000
(порт по умолчанию: 8000)
У меня была такая же проблема, как и ваш пост. Решение заключается в том, что вы должны запустить его с localhost (wamp или xamp). Это будет сделано.
Это вдохновлено ответом Томаса выше. Но с одной оговоркой, что я хотел распространять только HTML, поэтому я вручную преобразовал js в dataURL. и установите в нем флажок URL-адреса данных.
const myWorker = new Worker("data:application/x-javascript;base64,b25tZXNzYW...");
Другой обходной путь - использование веб-сервера Google для расширения Chrome. Выберите свой рабочий каталог и запустите сервер, Готово!
Простой способ сделать локальный http-сервер в Chrome это приложение:
Веб-сервер для Chrome
Описание:
Веб-сервер для Chrome обслуживает веб-страницы из локальной папки по сети, используя HTTP. Работает в автономном режиме. Web Server для Chrome - это HTTP-сервер с открытым исходным кодом (MIT) для Chrome.
Он работает везде, где у вас установлен Chrome, так что вы можете взять его где угодно. Это даже работает на хромбуках ARM.
Теперь у него есть возможность прослушивания в локальной сети, чтобы другие компьютеры могли получить доступ к вашим файлам. Кроме того, он может попытаться получить интернет-адрес.
Многие люди используют это, чтобы сделать основные веб-разработки на Chromebook. Это также удобно для обмена файлами по локальной сети между компьютерами или даже в Интернете.
После установки перейдите на http://127.0.0.1:8887/
И это не небезопасно, так как флаг --allow-file-access-from-files
Вам нужен веб-сервер для запроса по протоколу HTTP вместо локального файла и работает правильно:)
Chrome
загрузить файл, но не могу его запустить. использование Firefox
, Это работает для меня.
С Python 2.x более широко развернутым, чем Python 3.x, что-то вроде python -m SimpleHTTPServer 8000
в более широком смысле, и не только для Mac OS X. Я нашел это необходимым для использования, например, в Cygwin.
С этим, этот пример работал как чемпион.
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 мс.
Вероятно, причина в том, что Chrome не позволяет загружать веб-работников при запуске сценариев из локального файла. И я пытаюсь запустить код на моем Firefox, тоже не могу.
Чтобы загрузить веб-воркер из файла в проекте, настроенном с помощью Webpack и TypeScript, я использовал скрипт, предложенный Томашем Зато. Однако мне пришлось изменить рабочий файл.
рабочий.тс
(() => {
console.log("worker_function loaded");
// @ts-ignore
window.worker_function = () => {
self.onmessage = ({ data: { question } }) => {
// @ts-ignore
self.postMessage({
answer: 42,
});
};
}
})();
index.ts
async function run() {
console.log('run()');
const worker = new Worker(
// @ts-ignore
URL.createObjectURL(new Blob(["("+worker_function.toString()+")()"], { type: 'text/javascript' }))
);
worker.postMessage({
question: 'The Answer to the Ultimate Question of Life, The Universe, and Everything.',
});
worker.onmessage = ({ data: { answer } }) => {
console.log(answer);
};
}
run();
index.html
<html lang="en-us">
<head>
<meta charset="utf-8" />
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>Offscreen canvas with web worker sample project</title>
<script async type="text/javascript" src="worker.js"></script>
<script async type="text/javascript" src="app.js"></script>
</head>
<body>
<h1>web worker sample project</h1>
</body>
</html>
webpack.config.js (версия 5)
const path = require("path");
const CopyPlugin = require("copy-webpack-plugin");
module.exports = {
mode: "production",
entry: {
app: "./src/index.ts",
worker: "/src/worker.ts"
},
output: {
filename: "[name].js",
path: path.resolve(__dirname, "build")
},
performance: {
hints: false
},
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/
},
]
},
resolve: {
extensions: [".js", ".ts"]
},
plugins: [
new CopyPlugin({
patterns: [
{ from: "src/index.html", to: "" }
]
})
]
};
Да, он не будет работать в chorome, если вы загружаете локальный файл. Но это будет хорошо работать в браузере Firefox. И вы должны добавить ниже код в файле HTML.
<head>
<meta charset="UTF-8" />
</head>