Underscore.js _.template导致Chrome扩展程序出错

时间:2012-01-10 17:12:25

标签: javascript google-chrome-extension underscore.js

如果我在Google Chrome扩展程序中使用underscore.js_.template(),我会在控制台中收到以下错误:

  

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

有没有办法解决这个错误?

6 个答案:

答案 0 :(得分:7)

非常感谢Chromium列表撰稿人指出要以下划线的方式创建Function对象,需要manifest.json content_security_policy选项包含'unsafe-eval ”。

例如,您的manifest.json可能是

{
  "manifest_version": 2,
  ...
  "content_security_policy": "script-src 'self' 'unsafe-eval'",
  ...
}

然后下划线行为将起作用,因为此策略允许它。有关该格式的详细信息,请参阅此选项here上的Chrome文档。

答案 1 :(得分:5)

不幸的是我不认为你可以在chrome扩展中使用underscore.js的_.template()...至少使用新的manifest.json版本2.同样适用于尝试使用{{ 3}}

  

来自Google Chrome扩展程序的jQuery Template plugin页面:

     
    

没有放松对执行内联JavaScript的限制的机制。特别是,设置包含unsafe-inline的脚本策略将不起作用。这是故意的。

  

我将查看其他模板引擎,这些引擎有望不使用 new Function 对象。

答案 2 :(得分:4)

我使用Underscore.js因为我希望Backbone.js用于我的Chrome扩展程序,我只是将模板引擎更改为Mustache〜如果你有相同的原因,你也可以使用Underscore.js对于Backbone,只是不要使用_.template()函数。

答案 3 :(得分:1)

Google刚刚发布了一个新文档,讨论了解决此问题的方法?

http://code.google.com/chrome/extensions/trunk/sandboxingEval.html

答案 4 :(得分:0)

如上所述,清单v2限制禁止使用Eval,新函数和内联脚本 - 即使在使用内容安全策略时:v2扩展中的there's no way to relax this security policy

大多数模板库在某些时候都会使用evals。 一种解决方案是重写扩展,以便所有逻辑都驻留在javascript中,而模板中没有任何内容;在这种情况下,google jstemplate等解决方案应该可以使用。

但是,可以选择在sandboxed iframe中执行Eval和new Function,例如清单中包含以下行:

"sandbox": {
    "pages": [
      "page1.html",
      "directory/page2.html"
    ]
},

沙盒页面无法访问扩展程序或应用程序API,也无法直接访问非沙盒页面(它可以通过postMessage()与它们通信)。您可以使用特定CSP进一步限制沙盒权限

现在,github eval in iframe上的Google Chrome小组就如何通过与沙盒iframe进行通信来解决问题以及short analytics tutorial

提供了一个完整的示例

希望有些库会显示使用这种机制来提供与标准模板使用的完全兼容性,尽管出于性能原因我建议尽可能多地从模板中删除逻辑......

感谢Google,在阵容中有很多扩展重写:(

答案 5 :(得分:0)

您可以使用jQuery的$('<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);

E.g。如果你知道替换数据是无害的,那么使用dirty方法重写简单的jquery.tmpl模板非常快。