28

我想知道人们是否对动态生成 HTML 的最佳方式有强烈的看法,尤其是对于基于 Ajax 的应用程序。

您是否只是使用服务器端脚本创建 HTML 代码,然后将其发送到页面,或者可能只是返回一个 JSON 字符串并让 Javascript 完成这项工作。

在我个人看来,第一种方式将表示层与逻辑联系得太紧密,使其更难更改,维护起来简直就是一场噩梦。第二种方法虽然是我的首选方法,但当项目的复杂性增加时,也成为维护的噩梦。

我正在考虑使用 Javascript 模板系统作为另一层,只是为了使代码更健壮且不那么死板。任何人都对轻量级和非常好的 JS 模板系统有好的想法?

4

5 回答 5

16

http://ejohn.org/blog/javascript-micro-templating/是一个非常出色的 hack。最终结果非常干净。

于 2010-01-22T00:30:50.940 回答
10

我也更喜欢带有客户端 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('&amp;').split('<').join('&lt;').split('"').join('&quot;');
}

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 中的新元素创建东西使用了类似的样式。)

于 2010-01-22T00:55:26.357 回答
3

+1 年前,我们启动了一个新的 Web 应用程序,并且需要一种在浏览器中从 JSON 数据呈现 HTML 的方法。
我们希望它与 XML/XSLT 转换一样快。

我们的答案是 JS 模板引擎PURE

与周围的大多数 JS 模板库不同,它保持 HTML 不变(根本没有奇怪的标签),除了一些符号外,它没有带来新的语言学习,只有 JS 和 HTML。

我使用它的方式:

  • 直接在页面中构建静态 HTML
  • 然后一步步添加JS逻辑,HTML逐步变得鲜活起来
  • 一旦你习惯了,HTML 和 JS 都可以有一个安全的独立开发生活,并且可以在设计师和 JS 开发人员之间分开工作
于 2010-01-22T01:59:32.627 回答
1

我们有一个系统,其中大量数据以 JSON 格式从服务器传递,然后通过客户端的 javascript 模板引擎进行处理。在 .Net 4.0(甚至可能是 3.5 sp1,我不确定)中,这可以使用Client Templates来完成。

我宁愿传递 JSON 而不是发送 html。将数据和视图分开总是好的。

于 2010-01-22T00:35:19.793 回答
0

如果你想保留 MVC 框架,你应该让你的模板框架做模板。AJAX 应该只执行服务器请求,它执行所有数据库和业务逻辑,然后将 URL 返回到应该加载的模板。

于 2010-01-22T00:31:11.297 回答