CSP-safe ES6 Template Templates

Is there a template engine that will parse ES6 template literal -style templates (for example "string ${var}") without violating the Content- Security Policy Restriction (CSP) when evaluating the script?

CSP limits for script evaluation prevent eval, new Function, setTimeout(string)and setInterval(string).

There are a few template engines that can provide or change, to ensure that something like templates templates ES6 style, such as Resig the John MicroTemplates , lodash _.template and DoT.js . However, everyone seems to violate CSP using new Function.

In a way, it would be convenient if it varcould be unlimited Javascript, but for obvious reasons it might not be possible. However, I would need to modify the engine to format the output as desired.

Under the circumstances, performance is not a concern, and pre-compiling templates is not an option. Others discussed precompilation .

As an additional limitation, content is text, not HTML. I don’t think that DOM-based template engines like Knockout or PURE will not work efficiently as a result.

My first thought is to start with mustache.js and change it from there (that is, change it mustache.tags = ['${', '}']or do it yourself , but I would appreciate any thoughts on this topic in general, since it seems quite difficult to discuss CSPs and templates.

+4
source share
1 answer

If you only need a replacement for the key value, you can do this with a simple function such as templateReplace, which I provide below. No eval, just regular expressions.

" 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>
Hide result
+1

All Articles