我找到了一种简单的方法来制作它,因此默认情况下所有模板都被转义。由于 Backbone 使用 Underscore 作为它的模板引擎,我搜索了一下,发现您可以使用 _.templateSettings 自定义下划线分隔符,描述为 here on the Underscore site。请注意,如果您确保所有的 html 都是使用这些模板写出的,那么您将涵盖所有 XSS。所以不要在一些简单的场景中跳过使用模板,在这些情况下也可以使用它们来避免 XSS!
你可以用这个小提琴来测试它:http://jsfiddle.net/vx0pw2n0/
所以我所做的只是让<%= 和<%- 默认用于显示转义数据。评估标签<% 仍然存在,可以使用print 语句输出您想要的任何HTML。我还介绍了一个新标签<%cleanHtml,它可以用来输出HTML而不用转义,也不需要说print(someVariable)
<script type="text/javascript">
//
// This is the important part - The part that changes what underscore uses
// for template delimiters.
//
_.templateSettings =
{
escape: /<%[=-]([\s\S]+?)%>/g,
interpolate: /<%cleanHtml([\s\S]+?)cleanHtml%>/g,
evaluate: /<%([\s\S]+?)%>/g
};
// Test it out
var t = _.template($('#t').html());
var html = t({ title: '<b>pancakes</b>' });
$("#target").html(html);
console.log(html);
</script>
<!-- Sample Underscore Template showing different ways of using it -->
<script id="t" type="text/x-underscore">
<div><%= title %></div>
<div><%- title %></div>
<div><%safeHtmlOnly title safeHtmlOnly%></div>
<div><% print(title) %></div>
</script>
<div id="target"></div>
在全球范围内开展这项工作
要使其在全局范围内工作,您可能必须将 Underscore 配置为模块,可以这样做:
作为对 Backbone 的依赖实现
配置 Require.js 模块
// When you initially setup require.js, add a new module to configure underscore
// Make it a dependency of backbone, so it'll always be loaded whenever
// backbone is used.
require.config({
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscoreConfig', 'underscore', 'jquery'],
exports: 'Backbone'
},
jquery: {
exports: 'jQuery'
}
}
});
underscoreConfig.js
define(['underscore'], function (_) {
'use strict';
_.templateSettings =
{
escape: /<%[=-]([\s\S]+?)%>/g,
interpolate: /<%cleanHtml([\s\S]+?)cleanHtml%>/g,
evaluate: /<%([\s\S]+?)%>/g
};
return _;
});