4

是否有一個模板引擎能夠在不違反內容安全策略(CSP)限制腳本評估的情況下分析ES6 template literals(例如"string ${var}")風格的模板?CSP安全ES6模板文字

CSP restrictions on script evaluation阻止eval,new Function, setTimeout(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的討論缺乏,我會在一般的話題有什麼想法感激和模板。

+0

「在這種情況下的表現是不是一個問題」 - 用與string.replace回調呢?回調可以像'return vars [key];'一樣簡單。 –

+0

我想這是值得一提的ES6模板是CSP安全的(但請注意,他們確實將網站暴露給腳本)。 –

+0

你是什麼意思「*方便如果'var'可以不受限制Javascript *」'? – Bergi

回答

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>