【问题标题】:Underscore.js _.template causes error from Chrome extensionUnderscore.js _.template 导致 Chrome 扩展出错
【发布时间】:2012-01-10 17:12:25
【问题描述】:

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

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

有什么办法可以解决这个错误吗?

【问题讨论】:

  • 您可能还会看到Refused to execute inline script because of Content-Security-Policy
  • X-WebKit-CSP: script-src 'unsafe-eval';

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


【解决方案1】:

非常感谢 Chromium 列表的贡献者,他们指出要以下划线的方式创建 Function 对象,需要 content_security_policymanifest.json 选项包含“unsafe-eval”。

例如,您的 manifest.json 可能是

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

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

【讨论】:

【解决方案2】:

不幸的是,我认为您不能在 chrome 扩展中使用 underscore.js 的 _.template() ......至少对于新的 manifest.json 版本 2。尝试使用 @987654321 也是如此@。

来自 Google Chrome 扩展程序的 Content Security Policy 页面:

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

我将研究其他希望不使用 new Function 对象的模板引擎。

【讨论】:

  • 内联脚本限制仅适用于出现在 HTML 页面内的 JS(即“内联”JS)。您可以通过将先前内联的 JS 放入其自己的 .js 文件并通过脚本标签或通过其他机制加载它来绕过您在上面引用的特定内容。换句话说,您引用的内容似乎不适用于 unsafe eval 问题,特别是。
【解决方案3】:

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

【讨论】:

  • 使用 Mustache 代替 Underscore 的 _.template 对我来说是最简单的解决方案。
  • 是的,Mustache 可以 +1
【解决方案4】:

如上所述,Manifest v2 限制禁止使用 Eval、new Function 和内联脚本 - 即使在 v2 扩展中使用内容安全策略:there's no way to relax this security policy

大多数模板库有时会使用 eval。 一种解决方案是重写您的扩展,以便所有逻辑都驻留在 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 以及 short analytics tutorial 通信来规避问题

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

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

【讨论】:

    【解决方案5】:

    Google 刚刚发布了一份讨论此问题解决方案的新文档?

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

    【讨论】:

    • 链接已失效
    【解决方案6】:

    您可以使用 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);
    

    例如如果您知道替换数据无害等,使用脏方法重写简单的 jquery.tmpl 模板非常快。

    【讨论】:

      猜你喜欢
      • 2016-08-25
      • 2014-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多