javascript 铬包应用程序中的评估
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11897112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
eval in chrome package app
提问by Charles
I would like to create a package app chrome extension to allow the user to write and execute javascript code (like a javascript console).
我想创建一个包应用程序 chrome 扩展,以允许用户编写和执行 javascript 代码(如 javascript 控制台)。
I would like to use the eval()
function to execute the JS code.
我想使用该eval()
函数来执行 JS 代码。
The classic javascript eval
function throws an error when it's called from a chrome extension:
经典的 javascripteval
函数在从 chrome 扩展中调用时会引发错误:
Uncaught Error: Code generation from strings disallowed for this context
未捕获的错误:此上下文不允许从字符串生成代码
To use eval
in a chrome extension people need to use a sandbox, but when I write the sandbox in the manifest I get this error:
要eval
在 chrome 扩展中使用,人们需要使用sandbox,但是当我在清单中编写沙箱时,我收到此错误:
There were warnings when trying to install this extension: 'sandbox' is not allowed for specified package type (theme, app, etc.).
尝试安装此扩展时出现警告:指定的包类型(主题、应用程序等)不允许使用“沙盒”。
UPDATE
更新
According to this issue, sandboxes are not supported for package apps, so I have two questions:
根据这个问题,包应用程序不支持沙箱,所以我有两个问题:
Is there another method which I can use instead of
eval()
?Is it possible to use
eval
without a sandbox? (I think probably not for security reasons?)
还有另一种方法可以代替
eval()
吗?是否可以在
eval
没有沙箱的情况下使用?(我认为可能不是出于安全原因?)
回答by apsillers
UPDATE:
更新:
Since at least January 2013, Chrome now permits the unsafe-eval
Content Security Policy (CSP) directive, which allows eval
execution outside of a sandbox:
至少从 2013 年 1 月起,Chrome 现在允许unsafe-eval
内容安全策略 (CSP) 指令,该指令允许eval
在沙箱外执行:
The policy against
eval()
and its relatives likesetTimeout(String)
,setInterval(String)
, andnew Function(String)
can be relaxed by adding'unsafe-eval'
to your policy
针对
eval()
及其亲属的保单如setTimeout(String)
,setInterval(String)
, 并且new Function(String)
可以通过添加'unsafe-eval'
到您的保单中来放松
Add an appropriate CSPto you extension manifest, like:
向您的扩展清单添加适当的CSP,例如:
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
The bug you refer tois now marked fixed
, and has been included since Chrome 22.
您提到的错误现在被标记为fixed
,并且自 Chrome 22 以来已包含在内。
Prior to the introduction of 'unsafe-eval'
, there was no way to have the CSP of a manifest_version: 2
extension allow execution of arbitrary text as code. At the time, Google made it clear there was no way to remove this restriction (outside of sandboxing):
在引入 之前'unsafe-eval'
,没有办法让manifest_version: 2
扩展的 CSP允许将任意文本作为代码执行。 当时,谷歌明确表示没有办法消除这个限制(沙盒之外):
Inline JavaScript, as well as dangerous string-to-JavaScript methods like
eval
, will not be executed... There is no mechanism for relaxing the restriction against executing inline JavaScript. In particular, setting a script policy that includesunsafe-inline
will have no effect. This is intentional.
内联 JavaScript 以及危险的字符串到 JavaScript 方法(如
eval
)将不会被执行......没有机制可以放松对执行内联 JavaScript 的限制。特别是,设置包含的脚本策略unsafe-inline
将不起作用。这是故意的。
As mentioned above, this restriction can now be relaxed.
如上所述,现在可以放宽此限制。
回答by mangini
I suppose you are talking about the new packaged app (manifest version 2), right?
我想您是在谈论新的打包应用程序(清单版本 2),对吗?
Sandboxes can be used in the new packaged apps, absolutely. Last week I just uploaded a samplewhich does exactly that: A window sends a message to a hidden sandboxed iframe, the iframe compiles a handlebar template (here it could use eval instead) and returns the compiled HTML to the hosting page, which shows the result.
沙盒绝对可以在新的打包应用程序中使用。上周我刚刚上传了一个完全这样做的示例:一个窗口向一个隐藏的沙盒 iframe 发送消息,iframe 编译一个把手模板(在这里它可以使用 eval 代替)并将编译的 HTML 返回到托管页面,它显示了结果。
You can also check this other sample, which does exactly what you want.
您还可以检查这个其他示例,它完全符合您的要求。
So, to directly answer your questions:
所以,直接回答你的问题:
1) No, because of CSP restrictions. The only way to evaluate dynamic JavaScript in Chrome Packaged Apps is the sandboxed iframe. If that's not an option to your app, you could also send and evaluate the JavaScript content in your server and return only the results to the user (although this breaks the offline feature of Chrome Packaged Apps)
1) 不可以,因为 CSP 限制。在 Chrome Packaged Apps 中评估动态 JavaScript 的唯一方法是沙盒 iframe。如果这不是您的应用程序的选项,您还可以在服务器中发送和评估 JavaScript 内容,并仅将结果返回给用户(尽管这会破坏 Chrome Packaged Apps 的离线功能)
2) No, you can only use eval() in a sandboxed iframe.
2) 不,您只能在沙盒 iframe 中使用 eval()。
回答by rob
I came to this answer after an Angular.js chrome app I was starting gave the same error. The author did not mention Angular.js but if anyone else comes across this you need to add an additional directive to your web page e.g.
在我开始的 Angular.js chrome 应用程序出现同样的错误之后,我得到了这个答案。作者没有提到 Angular.js,但如果其他人遇到这个,你需要在你的网页中添加一个额外的指令,例如
<html ng-app ng-csp>
...
This puts angular in CSP-safe mode https://docs.angularjs.org/api/ng/directive/ngCsp
这将 angular 置于 CSP 安全模式 https://docs.angularjs.org/api/ng/directive/ngCsp
回答by Gabriel Bazán
You could use : $scope.$eval() from angular.
您可以使用 : $scope.$eval() 从角度。
回答by AshHeskes
You could try...
你可以试试...
function evalMe(code){
var script = document.createElement('script');
script.innerText = code;
document.querySelector('head').appendChild(script);
}
This should create the same effect, unless they have disabled it as well, but from my knowledge this is fine. Of course if the script errors
you will not hear about it unless you do some wrapping of the string
to eval
e.g.
这应该会产生相同的效果,除非他们也禁用了它,但据我所知,这很好。如果脚本当然errors
,你不会听到它,除非你做的一些包裹string
,以eval
如
function myHandler(err){
// handle errors.
}
function evalMe(code){
var script = document.createElement('script');
var wrapper = '(function(){ try{ @@ }catch(err){ myHandler(err); } })()';
// Make sure the string has an ending semicolon
code = code[code.length-1] === ';' ? code : code + ';';
script.innerText = wrapper.replace('@@', code);
document.querySelector('head').appendChild(script);
}
Alternately you could use the official mechanism
或者,您可以使用官方机制
http://developer.chrome.com/beta/extensions/tabs.html#method-executeScript
http://developer.chrome.com/beta/extensions/tabs.html#method-executeScript
However this would require you to have a background pageand employ message passingbetween your app
page and the background page.
但是,这需要您有一个背景页面并在您的页面和背景页面之间使用消息传递app
。
UPDATE:Working Method
更新:工作方法
You can create an eval
like method using an iframe and a base64
encoded dataURI
that handles message passing between the extension page and the <iframe>
. You can grab a working copy of the code on github. To use simply clone or download the repo, and install the 'client' dir
as an unpackaged extension in the chrome extension manager. The code driving the plugin resides in app.js
您可以创建一个eval
使用iframe和类似方法base64
进行编码dataURI
的扩展页和之间传递,处理消息<iframe>
。您可以在 github 上获取代码的工作副本。要使用简单的克隆或下载 repo,并dir
在 chrome 扩展管理器中将“客户端”安装为未打包的扩展。驱动插件的代码位于app.js
Use the iframeEval to test, the error notification is a little buggy but hey, the eval
works.
使用 iframeEval 进行测试,错误通知有点错误,但是嘿,eval
有效。
@appsillers In order to get your plugin working without any additional code, you could overwrite the eval
method on you extensions window
with the iframeEval
method in the code.
@appsillers 为了让您的插件在没有任何额外代码的情况下工作,您可以使用代码中的eval
方法覆盖扩展window
上的iframeEval
方法。
回答by elclanrs
Here is an example of what will NOT work, as all strings with code will be rejected in Chrome packaged apps:
这是一个不起作用的示例,因为 Chrome 打包的应用程序中将拒绝所有带有代码的字符串:
//To run some code from a string without `eval` just do this:
var code = new Function(yourCodeString);
code();