27

我想创建一个包应用程序 chrome 扩展,以允许用户编写和执行 javascript 代码(如 javascript 控制台)。

我想使用该eval()函数来执行 JS 代码。

从 chrome 扩展程序调用经典的 javascripteval函数时会引发错误:

未捕获的错误:此上下文不允许从字符串生成代码

eval在 chrome 扩展中使用,人们需要使用sandbox,但是当我在清单中编写沙箱时,会出现以下错误:

尝试安装此扩展时出现警告:指定包类型(主题、应用程序等)不允许使用“沙盒”。

更新

根据这个问题,包应用程序不支持沙箱,所以我有两个问题:

  1. 我可以使用另一种方法来代替eval()吗?

  2. eval没有沙箱可以使用吗?(我认为可能不是出于安全原因?)

4

6 回答 6

32

更新:

至少从 2013 年 1 月开始,Chrome 现在允许使用unsafe-eval内容安全策略 (CSP) 指令,该指令允许eval在沙盒之外执行:

可以通过添加到您的保单中来放宽针对eval()及其亲属的保单,如setTimeout(String),setInterval(String)new Function(String)'unsafe-eval'

向您的扩展清单添加适当的CSP ,例如:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"

您提到的错误现在标记为fixed,并且自 Chrome 22 起已包含在内。

在引入 之前'unsafe-eval',没有办法让manifest_version: 2扩展的 CSP 允许将任意文本作为代码执行。 当时,谷歌明确表示没有办法消除这个限制(沙盒之外):

内联 JavaScript 以及危险的字符串到 JavaScript 方法(如eval)将不会被执行......没有机制可以放宽对执行内联 JavaScript 的限制。特别是,设置包含的脚本策略unsafe-inline将不起作用。这是故意的。

如上所述,这个限制现在可以放宽了。

于 2012-08-12T23:03:14.153 回答
6

我想您是在谈论新的打包应用程序(清单版本 2),对吧?

沙盒绝对可以在新的打包应用程序中使用。上周我刚刚上传了一个示例,它确实做到了:一个窗口向隐藏的沙盒 iframe 发送消息,iframe 编译一个把手模板(这里它可以使用 eval 代替)并将编译后的 HTML 返回到托管页面,它显示结果。

您还可以检查this other sample,它完全符合您的要求。

所以,直接回答你的问题:

1) 否,因为 CSP 限制。在 Chrome 打包应用程序中评估动态 JavaScript 的唯一方法是沙盒 iframe。如果这不是您的应用程序的选项,您还可以在服务器中发送和评估 JavaScript 内容,并仅将结果返回给用户(尽管这会破坏 Chrome 打包应用程序的离线功能)

2) 不,您只能在沙盒 iframe 中使用 eval()。

于 2012-08-14T19:16:10.847 回答
1

你可以试试...

function evalMe(code){
    var script = document.createElement('script');
    script.innerText = code;
    document.querySelector('head').appendChild(script);
}

这应该会产生相同的效果,除非他们也禁用了它,但据我所知,这很好。当然,如果脚本errors你不会听到它,除非你对 to 进行一些包装stringeval例如

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

或者,您可以使用官方机制

http://developer.chrome.com/beta/extensions/tabs.html#method-executeScript

但是,这将要求您有一个背景页面并在您的页面和背景页面之间使用消息传递。app

更新:工作方法

您可以eval使用 iframe 和base64处理dataURI扩展页面和<iframe>. 您可以在 github 上获取代码的工作副本。要使用简单的克隆或下载 repo,并dir在 chrome 扩展管理器中将“客户端”安装为未打包的扩展。驱动插件的代码位于app.js

使用 iframeEval 进行测试,错误通知有点错误,但嘿,eval工作正常。

@appsillers 为了让您的插件在没有任何额外代码的情况下工作,您可以使用代码中的eval方法覆盖扩展window上的iframeEval方法。

于 2012-08-14T16:43:38.677 回答
1

在我开始的 Angular.js chrome 应用程序给出了同样的错误之后,我得到了这个答案。作者没有提到 Angular.js,但如果其他人遇到这个,你需要在你的网页上添加一个额外的指令,例如

<html ng-app ng-csp>
...

这将 Angular 置于 CSP 安全模式 https://docs.angularjs.org/api/ng/directive/ngCsp

于 2015-05-22T13:34:50.777 回答
1

您可以使用 : $scope.$eval() 从角度。

于 2016-07-20T19:19:35.770 回答
-1

这是一个不起作用的示例,因为所有带有代码的字符串都将在 Chrome 打包应用程序中被拒绝:

//To run some code from a string without `eval` just do this:
var code = new Function(yourCodeString);
code();
于 2012-08-10T07:24:21.977 回答