Function
对象需要在manifest.json
选项中包含'unsafe-eval'的content_security_policy
。manifest.json
可以是:{
"manifest_version": 2,
...
"content_security_policy": "script-src 'self' 'unsafe-eval'",
...
}
然后下划线的行为将起作用,因为此策略允许它。有关格式的更多信息,请参阅此选项的Chrome文档这里。
很遗憾,我认为您无法在chrome扩展内使用underscore.js的_.template()函数, 至少在新的manifest.json版本2中不行。同样适用于尝试使用jQuery模板插件。
来自Google Chrome扩展的内容安全策略页面:
没有放松执行内联JavaScript限制的机制。特别地,设置包括unsafe-inline的脚本策略将没有任何效果。这是有意为之的。
我将寻找其他模板引擎,希望它们不会使用new Function对象。
我使用 Underscore.js
是因为我想要在我的 Chrome 插件中使用 Backbone.js
,我只是把模板引擎改成了 Mustache
。如果你有同样的理由,你也可以在 Backbone 中使用 Underscore.js,但是不要使用 _.template()
函数。
Mustache
而不是Underscore的_.template
对我来说是最简单的解决方案。 - Kevin JantzerMustache
可以 +1 - Kirzilla谷歌刚刚发布了一份新文档,讨论了解决这个问题的方案吗?
http://code.google.com/chrome/extensions/trunk/sandboxingEval.html
$('<element .../>')
结构编写自己的模板迷你引擎。function myElement(text) {
var d = $('<div class="abc"/>');
d.text(text);
return d;
}
myElement('my text').appendTo(domParent);
一种不太优雅的方法:
var yourTemplate = '<div>${somevar}</div>';
function instTemplate(tmpl, text) {
return $(tmpl.replace(/\$\{somevar\}/g, text));
}
instTemplate(yourTemplate, 'your text').appendTo(domParent);
例如,如果您知道替换数据不会有害等情况,使用简单的jquery.tmpl模板重写是相当快速的,但这种方法可能不太规范。
如上所述,清单v2的限制禁止使用Eval、new Function和内联脚本 - 即使在与内容安全策略相互作用时也无法放松此安全策略。
大多数模板库在某个时候都会使用evals。 一种解决方案是重写您的扩展,以便所有逻辑都驻留在JavaScript中,而模板中没有任何东西; 在这种情况下,Google jstemplate等解决方案应该可用。
然而,有一个选项可以在sandboxed iframe内执行Eval和new Function,例如在清单中使用以下几行:
"sandbox": {
"pages": [
"page1.html",
"directory/page2.html"
]
},
沙盒页面将无法访问扩展或应用程序API,也无法直接访问非沙盒页面(可以通过postMessage()与它们通信)。您可以使用特定的CSP进一步限制沙盒权限
现在,Google Chrome团队有一个完整的示例github eval in iframe,介绍如何通过与沙盒iframe通信来规避问题,以及短分析教程
希望会有一些库使用这种机制来提供与标准模板使用的完全兼容性,尽管出于性能原因,我建议从模板中删除尽可能多的逻辑...
感谢Google,有很多扩展需要重写 :(