CSP安全的ES6模板文字

时间:2013-11-27 02:11:25

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

是否有模板引擎会以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。因此,我不认为面向DOM的模板引擎(如Knockout或PURE)无法有效工作。

我的第一个想法是从mustache.js开始并从那里进行修改(即更改mustache.tags = ['${', '}']DIY solution,但我会对此主题的任何想法感激不尽关于CSP和模板的讨论似乎很少。

2 个答案:

答案 0 :(得分: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;
}())
&#13;
demo 1 - {{key}} syntax
<div id="result1"></div>

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

答案 1 :(得分:1)

Micromustache库正是这样做的。版本6支持设置自定义打开和关闭标记(${},而不是{{}}),这使其更容易替换模板文字。 / p>