Chrome 包应用程序中的评估

eval in chrome package app

本文关键字:评估 应用程序 Chrome      更新时间:2023-09-26

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

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

经典的 javascript eval 函数在从 chrome 扩展调用时会抛出错误:

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

要在 chrome 扩展程序中使用 eval,人们需要使用沙箱,但是当我在清单中编写沙盒时,我收到此错误:

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

更新

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

  1. 有没有另一种方法可以用来代替eval()

  2. 是否可以在没有沙盒的情况下使用eval?(我认为可能不是出于安全原因?

更新:

至少从 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的脚本策略将不起作用。这是故意的。

如上所述,现在可以放宽此限制。

我想你说的是新的打包应用程序(清单版本 2),对吧?

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

您还可以检查此其他示例,该示例完全符合您的要求。

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

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

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

你可以试试...

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

这应该会产生相同的效果,除非他们也禁用了它,但据我所知,这很好。当然,如果脚本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);
}

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

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

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

更新:工作方法

您可以使用 iframe 和 base64 编码的dataURI创建类似eval的方法,该方法处理扩展页和<iframe>之间的消息传递。你可以在github上获取代码的工作副本。要使用,只需克隆或下载存储库,并将"客户端"dir作为未打包的扩展程序安装在 chrome 扩展管理器中。驱动插件的代码驻留在app.js

使用 iframeEval 进行测试,错误通知有点问题,但嘿,eval有效。

@appsillers 为了使插件无需任何其他代码即可工作,您可以使用代码中的iframeEval方法覆盖扩展window上的eval方法。

在我启动的 Angular.js chrome 应用程序出现相同错误后,我得出了这个答案。作者没有提到 Angular.js但如果其他人遇到这种情况,您需要在您的网页中添加一个额外的指令,例如

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

这使角度处于CSP安全模式https://docs.angularjs.org/api/ng/directive/ngCsp

你可以使用:$scope.$eval()来自angular。

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

//To run some code from a string without `eval` just do this:
var code = new Function(yourCodeString);
code();