使用最新的主干和下划线库(1.0.0/1.4.4)我找不出我的模板为什么不像我期望的那样转义。下面是一个简化版本:Backbone.js/Underscore.js:为什么我的模板不能转义
M = Backbone.Model.extend({});
V = Backbone.View.extend({
template: _.template("<%- attr %>"),
render: function() {
this.$el.html(this.template(this.model.attributes));
return this;
}
});
m = new M({attr: "<script>bad</script>"});
v = new V({model: m});
v.render();
console.log(v.el);
结果:
<div><script>bad</script></div>
这是很明显,没有逃脱。我验证过的模板,作为独立的代码,执行正确逃逸:
T = _.template("<%- attr %>");
console.log(T({attr: "<script>bad</script>"}));
产生的
<script>bad</script>
预期的结果所以某处内容越来越转义。如果有人知道在哪里,或者更好,如何防止它,我会非常感激。
斯蒂芬
更新:
想通了!虽然问题不是控制台本身,亩的答案确实指向了我的正确方向。为了解释,我需要对上面的示例代码稍加说明,以便它更准确地反映我的上下文。该上下文实际上并不是控制台输出,而是单元测试。我想验证我的代码是否正确防范XSS攻击,所以我写的单元测试(采用摩卡/兴农/柴/应):
v.$el.text().should.equal(m.escape("attr"));
那个测试不及格(意外),而下面测试路过(我不认为它应该是):
v.$el.text().should.equal(m.get("attr"));
罪魁祸首原来的元素对象上是toString()
方法。该方法,即console.log()
使用的方法可以使内容失效。在text()
函数中,jQuery也(间接)使用该方法。
我不确定这在所有浏览器中都是通用的,但在我的情况下使用.innerHTML()
可以避免使用toString()
unescape。所以正确的方法来写我的测试是
v.el.innerHTML().should.equal(m.escape("attr"));
http://stackoverflow.com/faq#signatures – forivall 2013-03-20 19:51:42