无论是前端还是后端,都存在着模板引擎。模板引擎有着丰富的表现力,使得我们可以根据不同的数据渲染出不同的页面结构以及内容。在es6中引入了模板字符串,使得我们可以在字符串中嵌入变量、表达式以及可以直接写多行字符串。另外,模板字符串还支持嵌套使用。这些特性,一些模板引擎基本的功能,我们可以用es6模板字符串来实现。
for 循环
- 一种比较直接的方式是:
1 | ${ |
可以看到,我们利用一个立即执行函数,在函数内写一个for循环来实现。
- 对以上的方法稍加优化,我们可以得到如下的代码:
1 | ${ |
我们利用了Array的reduce方法,从而不需要将代码封装在一个立即执行函数之中。
if else 条件判断
很容易想到用三目运算符:
${(data && data != '') ? `<div>${data}</div>` : `<div>no contnet</div>`}
如果只在存在数据时有相应的html,不存在数据时没有html,则可以这么写:
${(data && data != '') && `<div>${data}</div>`}
特殊字符转义
在模板中非常重要的一点是字符串的转义,因为涉及到安全的问题,一个简单的方式是利用标签模板:
var message = SaferHTML`<p>${bonk.sender} has sent you a bonk.</p>`;
上面的代码等价于:
var message = SaferHTML(templateData, bonk.sender);
其中, templateData 是一个不可变的字符串数组,在上例中为:
Object.freeze(["<p>", " has sent you a bonk.</p>"]
SaferHTML需要我们自己去实现:
1 | function SaferHTML(templateData) { |
从安全角度来看,这个 SaferHTML 非常脆弱。在 HTML 中,不同的地方需要用不同的方式去转义,SaferHTML 并没有做到。
另外一点是,这个方法只适用于没有嵌套使用模板字符串的情况,如果嵌套使用,那么一些不该被转义的字符串页会被转义。在这种情况下,我们还是老老实实地对每一处改转义的地方进行转义.
首先,需要编写一个转义函数:
1 | const reUnescapedHtml = /[&<>"'`]/g; // 需要被转码的字符 |
然后我们在每一个需要转义字符串的地方调用 escapeHTML 方法进行转义。
参考文献:
DOM based XSS Prevention Cheat Sheet
[Web 安全] 了解XSS与防范
模版字符串
i18n with tagged template strings in ECMAScript 6