Chrome无法加载网络工作者


109

我正在使用网络工作者的项目中。

在我的头部,我有以下代码:

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 2014年

Answers:


84

从本地文件运行脚本时,Chrome不允许您加载网络工作者。


6
根据这个答案Loading a local file, even with a relative URL, is the same as loading a file with the file: protocol.-网页能够随心所欲地访问文件系统并不是一件很酷的事情。
ChaseMoskal 2014年

41
-1 firsfox当然可以让您做到这一点,只要您使用文件作为来源(例如,您正在浏览器中查看本地文件)。只是铬被打破了。
托马什Zato -恢复莫妮卡

3
Firefox仍然可以运行(从file://是),Chrome在这种情况下不能运行。
Evil

55

我使用一种解决方法。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'})));

这个解决方案很好。为什么在这个世界上没有什么是完美的?每个软件都在用错误,缺陷,幼稚的行为等来激怒用户。Firefox也很傲慢,因为它拒绝支持“剪切路径” css属性。
Ĭsααc吨իεβöss

我不是js开发人员,在这里不了解脚本标记的用途。窗口!=自我检查是什么?有人可以解释这个加载顺序吗?谢谢。
沙伦

如果脚本标记与HTML位于同一目录中,则它们将由Google chrome加载。window!=seld检查代码是否在Web Worker中运行。如果您直接在其他上下文中加载javascript文件,这将使此代码可移植。
托马什Zato -恢复莫妮卡

1
@ treeseal7应该在Web Worker上下文中执行的代码。
托马什Zato -恢复莫妮卡

2
我应该注意,您不能从这样编写的工作程序中使用importScript。至少,并非没有其他解决方法。因此,对于多文件工作者,您将需要进行更多的篡改。
SlugFiller

41

Noble Chicken已正确解释了该问题,但是我有一个更通用的解决方案。不用安装wamp或xamp,可以使用python导航到项目所在的文件夹,然后键入:python -m http.server

就是这样,您将在该文件夹上有一个正在运行的服务器,可以从localhost访问。


13
Macs可能需要随python -m SimpleHTTPServer 8000其一起加载<Python 3(只是为了保存另一个Google搜索:D)
siege_Perilous 2015年

3
您还可以安装http-server节点模块,然后从终端导航到所需的文件夹并运行'http-server -p 3000'。
张欢

值得一提的是,此脚本“ python -m http.server”需要
Python3。– Milema

也可以尝试php -S localhost:8000
威廉Entriken

29

您也可以使用--allow-file-access-from-files启动Chrome时,您标志。

MacOsX的示例:

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

更多信息:chrome的Web worker设置


在Windows命令窗口上,导航至:“ C:\ Users \ NAME \ AppData \ Local \ Google \ Chrome SxS \ Application”,然后运行chrome.exe --allow-file-access-from-files,然后复制本地文件路径例如c:\ temp \ myWeb \ index.html并粘贴到打开的浏览器的url中,完成。
里程碑

4
您还可以创建快捷方式,并在目标路径中传递标志。
斯蒂芬

1
哦,关于链接的问题,请记住在启动带有标志的窗口之前关闭所有Chrome窗口。
斯蒂芬

是的,一个其他选项,也可以编写一个Chrome扩展与发言权允许在它的表现:“权限”:“文件:// * / *”],就像stackoverflow.com/questions/19493020/...
的Mickaël

注意:“您必须先关闭Chrome的所有窗口,然后再打开带有--allow-file-access-from-files标志的Chrome 。” 如stackoverflow.com/a/21771754/325418上所述
nonopolarity,

15

这是由于安全限制。您需要使用http://https://协议来代替file:///

如果安装了NodeJS,则只需执行以下操作。 -请注意,这是许多可用选项之一

安装本地网络服务器

$ npm install -g local-web-server

现在,您可以在要访问其内容的任何文件夹中使用它http

$ ws

导航至http://localhost:8000(默认端口:8000)


6

我也遇到了与您的帖子相同的问题。解决方案是您必须使用localhost(wamp或xamp)运行它。会完成的。


哇,我永远不会找到这个-谢谢!(我希望感谢您的评论)
dcromley 2015年



3

Chrome加载文件但无法运行。使用Firefox。它为我工作。


1
解释一下我的不赞成意见:最好从发表评论开始,也许更多地询问他们的浏览器支持要求,而不是作为答案提交。鉴于用户已经说过关于跨浏览器的支持,这似乎很可能不是一个答案。
Thomas Poole

如果您已经仔细阅读了该问题,那么我相信您在投票之前不会将投票否决为三!用户说Chrome无法加载工作程序。不,Chrome可以加载工作程序,但无法运行它。我之所以将其作为答复的原因是,首先是在一年前提出了这个问题,其次是许多回答,它们说Firefox没有运行该工作程序,而我无法对所有工作程序进行评论。我只是在解释,但您有权投反对票或投反对票。
Hocine Ben

3

在Chrome中制作本地http服务器的简单方法是此应用:

Chrome的Web服务器

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

描述:

Chrome浏览器的Web服务器使用HTTP从网络上的本地文件夹提供网页。脱机运行。Chrome的Web服务器是Chrome的开源(MIT)HTTP服务器。

它可以在安装了Chrome的任何地方运行,因此您可以随身携带它。它甚至适用于ARM chromebook。

现在,它可以选择在本地网络上侦听,以便其他计算机可以访问您的文件。此外,它可以尝试获取Internet地址。

许多人使用它在chromebook上进行基本的Web开发。它也很方便在计算机之间甚至在Internet上通过本地网络共享文件。

安装后,导航至http://127.0.0.1:8887

并且它不是不安全的标志--allow-file-access-from-files


这真太了不起了!现在,我可以与本地文件系统中的Web工作者一起运行我的reactJS应用程序。再简单不过了!
杰森

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 OSX。例如,我发现必须在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;
}

如前所述,Chrome不支持它。我喜欢在同一文件中定义我的工作人员。这是一个可行的解决方法,它将id=num每500ms 增加一次在元素的innerHTML中找到的数量。


1

可能的原因是chrome不允许您从本地文件运行脚本时加载网络工作者。而且我尝试在我的Firefox上运行代码,也不能。


网络工作者file://在Firefox 51.0.1中运行良好
bryc

-6

是的,如果您正在加载本地文件,它将在chorome中不起作用。但是,它将在Firefox浏览器中正常工作。并且您必须在HTML文件中添加以下代码。

<head>
    <meta charset="UTF-8" />
</head>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.