如何构建优雅降级 AJAX 网页?

Posted

技术标签:

【中文标题】如何构建优雅降级 AJAX 网页?【英文标题】:How to build Graceful Degradation AJAX web page? 【发布时间】:2011-02-14 11:12:27 【问题描述】:

我想用“Graceful Degradation”构建网页。也就是说,网页功能甚至禁用了javascript。现在我必须对 AJAX 响应的格式做出设计决定。

如果禁用了 javascript,对服务器的每个 HTTP 请求都会生成 html 作为响应。浏览器使用返回的 HTML 进行刷新。没关系。

如果启用了 javascript,对服务器的每个 AJAX HTTP 请求都会生成……嗯,JSON 或 HTML。

如果是HTML,很容易实现。只需使用 javascript 将部分页面替换为返回的 HTML。而且,在服务器端,不需要太多的代码更改。

如果是 JSON,那么我必须再次在 javascript 中实现 JSON-to-html 逻辑,这几乎是服务器端逻辑的重复。 复制是邪恶的。我真的不喜欢它。好处是带宽使用比 HTML 更好,带来更好的性能。

那么,优雅降级的最佳解决方案是什么? AJAX 请求返回 JSON 还是 HTML 更好?

【问题讨论】:

一如既往地取决于你必须做什么,为什么你的页面需要 JS?仅适用于异步请求? JS 一般用于网页的丰富界面体验。部分而不是全部,JS 功能是从服务器异步请求资源。 【参考方案1】:

我认为对于任何特定情况都没有“最佳解决方案”。仅可能是针对特定解决方案的“适当解决方案”。这真的取决于你想要做什么。优雅降级对我来说意味着:

构建一个“足够好”的界面,可以在尽可能多的浏览器(桌面和移动)上运行。 不显眼地添加一些脚本(验证方法、界面元素,如选项卡和滑块等),这些脚本只有在加载页面的浏览器具有使其工作所需的功能时才会出现。

在服务器响应中使用 HTML 还是 JSON 是非常主观的,我经常发现自己很难在它们之间做出选择。有人可能会争辩说,例如,从服务器接收一堆键值对并将它们呈现到现有的选择元素中将意味着更多代码,因此会花费更多时间进行编码和更多潜在错误。相反,您可以简单地从服务器请求预先构建的选择元素,并将其注入容器中。构建元素的逻辑已经存在于服务器上,为什么要构建它两次,用两种不同的语言。

另一种观点是 JSON 最大限度地减少了带宽使用,因此值得付出额外的努力来解析一些 JSON 以在客户端上构建一些标记。我发现很容易不同意这种观点,原因有几个(我不是概括,不要误会我的意思)。首先,许多网络服务器被配置为压缩/放气/gzip 其输出,并且许多浏览器接受压缩内容。标记是非常可压缩的,因为它包含大量冗余 (<strong></strong>)。因此有理由认为 JSON 响应的大小不会比带有标记的响应小得多。其次,大型数据集可能意味着客户端上的执行时间相当长(讨厌的嵌套循环很常见 - 在此处弹出的一些问题中很明显)。

我对您的建议是尝试了解每种方法的优缺点,并利用这些信息。您可能想阅读以下内容:

http://www.quirksmode.org/blog/archives/2005/12/the_ajax_respon.html

【讨论】:

【参考方案2】:

IMO,使用 HTML 会带来更大的安全风险(MITM 脚本注入等)。在“重复”上节省的任何时间都应该真正花在附加之前的清理上。

JSON 可以安全地解析,并且通常更紧凑,如您所说,节省带宽。

我知道我会选择哪个 (JSON)。

【讨论】:

我认为 HTML 响应只有在包含内联 Javascript 代码时才有风险。由于 HTML 的生成是在服务器端控制的,所以它不应该是一个安全错误。【参考方案3】:

首先,请仔细考虑您是否真的需要同时支持启用 JavaScript 的用户和未启用 JavaScript 的用户。在我看来,AJAX 的伟大之处在于它将显示(HTML 的构造)与信息分开。

也就是说,这是一种可行的方法:

    编写一个服务器端程序,该程序执行您的页面需要执行的操作,并以最简单的形式返回答案(无论包含什么)。对于简单的输出——比如仅仅表明它是否有效——这可能只是一个数字或一个简单的字符串。对于任何比单个结果更复杂的东西,它可能是 XML。

    编写一个服务器端脚本,简单地调用您的程序并将结果输出为纯文本或 XML。

    编写另一个服务器端脚本,调用您的程序并从中构建一个 HTML 页面。

    在用户调用以运行例程的页面中,包含编写控件(例如按钮)的 javascript,当按下该控件时会发送 AJAX 请求以调用第一个脚本,然后解析结果并更新页面因此。还包括另一个控件,在 NOSCRIPT 标记中,以便启用 JS 的用户不会看到它,它执行标准表单提交以运行您的第二个脚本。所以你仍然需要两个脚本,但你的主要计算内容只完成一次。

【讨论】:

以上是关于如何构建优雅降级 AJAX 网页?的主要内容,如果未能解决你的问题,请参考以下文章

Javascript Ajax 优雅降级,有不同的页面?

渐进增强和优雅降级

渐进增强和优雅降级

symfony2 中的 Ajax 表单提交,为没有 javascript 的用户提供优雅的降级

渐进增强,优雅降级

网页设计时的渐进增强和优雅降级原则