【问题标题】:CSP-safe ES6 template literalsCSP 安全的 ES6 模板文字
【发布时间】:2013-12-12 12:22:13
【问题描述】:

是否有一个模板引擎可以解析ES6 template literals(例如"string ${var}")样式的模板,而不违反脚本评估的内容安全策略(CSP)限制?

CSP restrictions on script evaluation 阻止 evalnew FunctionsetTimeout(string)setInterval(string)

有许多模板引擎可以提供或修改以提供类似 ES6 样式的模板文字,例如 John Resig 的 MicroTemplates、lodash _.template 和 DoT.js。但是,使用new Function 似乎都违反了 CSP。

如果var 可以是不受限制的Javascript,在某些方面会很方便,但由于明显的原因,这可能是不可能的。但是,我需要能够修改引擎以根据需要格式化输出。

在这种情况下,性能不是问题,预编译模板不是一种选择。其他人有discussed pre-compilation

作为附加限制,内容是文本,而不是 HTML。因此,我认为 Knockout 或 PURE 等面向 DOM 的模板引擎不会有效地工作。

我的第一个想法是从 mustache.js 开始并从那里修改它(即更改 mustache.tags = ['${', '}']DIY solution,但我会很感激有关该主题的任何想法,因为似乎有很多缺乏关于 CSP 和模板的讨论。

【问题讨论】:

  • "在这种情况下,性能不是问题" -- string.replace 用回调然后呢?回调可以像return vars[key]; 一样简单。
  • 我想值得一提的是 ES6 模板是 CSP 安全的(但请注意,它们确实会将网站暴露给脚本)。
  • 你所说的“如果var可以是不受限制的Javascript就很方便了”`是什么意思?

标签: javascript ecmascript-6 content-security-policy template-strings


【解决方案1】:

如果您只需要键值替换,您可以使用一个简单的函数,例如我在下面提供的 templateReplace。不涉及 eval,只有正则表达式。

如果您需要包含“不受限制的 javascript”,具有类似 ${[1,2,3].join(', ')} 的内容,那么,正如您所承认的,您显然需要一个违反您的 CSP 政策的解决方案。

var templateReplace = function(html, data, keyTemplate) {
  if (!keyTemplate || typeof keyTemplate !== 'string' || keyTemplate.indexOf('key') === -1) {
    keyTemplate = '{{key}}';
  }
  return (Object.keys(data) || []).reduce(function(html, key) {
    var val = (data[key] !== undefined) ? data[key] : '';
    return html.replace(new RegExp(keyTemplate.replace('key', key), 'gi'), val);
  }, html);
};

// demo 1, using {{key}} syntax
(function() {
  var li = [{ text: 'one' }, { text: 'two' }, { text: 'three' }].map(function(d) {
    return templateReplace( '<li>Item: {{text}}</li>', d);
  });
  document.querySelector('#result1').innerHTML = li.join('\n')
}())

// demo 2, using ${key} syntax
(function() {
  var helloWorld = templateReplace('${hello} ${world}', { hello: 'Hello', world: 'World!' }, '\\${key}');
  document.querySelector('#result2').innerHTML = helloWorld;
}())
demo 1 - {{key}} syntax
<div id="result1"></div>

demo 2 - ${key} syntax
<div id="result2"></div>

【讨论】:

    【解决方案2】:

    Micromustache 库正是这样做的。版本 6 支持设置自定义打开和关闭标记(${} 而不是 {{}}),这使其更像是模板文字的直接替代品。

    【讨论】:

      猜你喜欢
      • 2016-09-11
      • 1970-01-01
      • 2016-12-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-01
      相关资源
      最近更新 更多