我也更喜欢带有客户端 HTML 创建逻辑的 JSON 响应。
不幸的是,大多数现实世界的客户端 HTML 编写脚本都被破坏了,其中包含许多 HTML 注入缺陷,这些缺陷很容易成为跨站点脚本安全漏洞。我认为这种信念是,因为您是在与自己的服务器而不是直接与敌对用户交谈,所以您在某种程度上是“安全的”,并且在将它们插入 HTML 时可以在没有正确字符串的情况下逃脱。这当然是胡说八道。
我总是看到类似的东西:
$('#mydiv').append('<em>Deleted '+response.title+'!</em>');
或者:
mydiv.innerHTML= '<p>Renamed to '+response.name+'</p>;
或者实际上是 Resig 的微模板 hack,默认情况下没有 HTML 转义。来吧,人们!我们才刚刚开始清理服务于服务器端 XSS 的损坏的 PHP 脚本的遗留问题,现在您想引入全新的大量客户端 XSS 漏洞吗?
叹。这就是弦乐的诱惑。我们认为我们了解它们,并且可以不择手段地将它们组合在一起。但是字符串是危险的,具有隐藏的上下文和逃避要求。如果您必须在客户端生成 HTML,您将需要这样的函数:
function h(s) {
return s.split('&').join('&').split('<').join('<').split('"').join('"');
}
mydiv.innerHTML= '<p>Renamed to '+h(response.name)+'</p>;
但我个人更喜欢 DOM 方法。与 SQL 的参数化一样,使用 DOM 方法通过将原始字符串直接与将使用它们的组件进行对话,从而消除了对字符串的处理。好的,DOM 的问题在于它相当冗长:
var p= document.createElement('p');
p.appendChild(document.createTextNode('Renamed to '+response.name))
mydiv.appendChild(p);
但是你总是可以定义辅助函数来减少它,例如:
mydiv.appendChild(makeElement('p', {}, 'Renamed to'+response.name));
(jQuery 1.4 中的新元素创建东西使用了类似的样式。)