为什么返回生成的HTML而不是JSON是一种不好的做法?还是?


301

使用JQuery或任何其他类似框架从自定义URL / Web服务中加载HTML内容非常容易。到目前为止,我已经使用过这种方法很多次,并且发现性能令人满意。

但是所有书籍,所有专家都试图让我使用JSON而不是生成的HTML。它比HTML优越得多吗?

它快很多吗?
它在服务器上的负载要少得多吗?

另一方面,我有一些使用生成的HTML的原因。

  1. 它是简单的标记,通常与JSON一样紧凑或实际上更紧凑。
  2. 错误更少,因为您得到的只是标记,而且没有代码。
  3. 在大多数情况下,编程将更快,因为您不必为客户端单独编写代码。

您站在哪一边?为什么?


值得注意的是,AJAX中的X是XML,而HTML在某一点上应该是XML。这个想法是HTML是人类和机器可读的数据(如JSON),而CSS可以进行演示。在这种情况下,在AJAX请求中发送HTML不会违反“关注点分离”的要求
code_monk '17

Answers:


255

实际上,我两面都是:

  • 当我需要在javascript端使用data时,我使用JSON
  • 当我需要在javascript端进行演示而不进行任何计算时,通常会使用HTML

使用HTML的主要优点是,当您要用Ajax请求返回的内容替换页面的整个部分时:

  • 在JS中重新构建页面的一部分非常困难
  • 您可能已经在服务器端有了一些模板引擎,这些引擎最初是用来生成页面的。为什么不重用它呢?

通常,至少在服务器上,我通常不会真正考虑“性能”方面:

  • 在服务器上,生成HTML或JSON的一部分可能不会产生太大的变化
  • 关于通过网络的内容的大小:好吧,您可能不使用数百KB的数据/ html ...在要传输的内容上使用gzip会产生最大的不同(不要在HTML之间进行选择)和JSON)
  • 不过,可以考虑的一件事是,您需要在客户端上从JSON数据重新创建HTML (或DOM结构)所需的资源...与将一部分HTML推入页面相比; -)

最后,一件绝对重要的事情:

  • 您需要花多长时间开发一个新系统,以JSON +代码的形式发送数据,而JS需要将JS作为HTML注入页面?
  • 仅返回HTML需要多长时间?以及是否可以重用一些已经存在的服务器端代码?


并回答另一个答案:如果您需要更新页面的多个部分,那么仍然存在将所有这些部分发送到一个大字符串中的解决方案/技巧,该大字符串将几个HTML部分组成一组,然后在JS中提取相关部分。

例如,您可以返回一些类似于以下内容的字符串:

<!-- MARKER_BEGIN_PART1 -->
here goes the html
code for part 1
<!-- MARKER_END_PART1 -->
<!-- MARKER_BEGIN_PART2 -->
here goes the html
code for part 2
<!-- MARKER_END_PART2 -->
<!-- MARKER_BEGIN_PART3 -->
here goes the json data
that will be used to build part 3
from the JS code
<!-- MARKER_END_PART3 -->

看起来并不太好,但是它确实很有用(我已经使用了好几次,主要是在HTML数据太大而无法封装成JSON的情况下):您正在为页面的各个部分发送HTML需要演示,并且您正在针对需要数据的情况发送JSON ...

...然后提取这些,JS子字符串方法将解决问题,我想;-)


6
所有数据最终都是表示形式。
西里尔·古普塔

47
@西里尔:嗯?我认为您是想说必须使用有用的数据,然后以某种形式将其显示在某处,我同意。但是,至少说数据表示形式似乎是错误的。
Vinko Vrsalovic

10
您好Vinko,注意“最终”吗?我的意思就是你的意思。只是想在这里进入报价单。哈哈!
西里尔·古普塔

37
基本问题是,您是否绝对肯定地最终确定除了HTML之外,您将不会使用此数据。因为一旦打包成HTML,数据将几乎无法恢复。使用JSON,您的后端可以与XML,SVG,数据库引擎,跨站点API以及其他上千个可以接受JSON的前端和系统一起使用。使用HTML,您将只能在HTML中使用它。
SF。

3
@SF:从服务器返回HTML时,请确保将HTML生成代码与访问数据库的代码分开。这样,我也可以轻松添加JSON表单。
Casebash 2010年

114

我主要同意这里所说的观点。我只想将它们总结为:

  • 如果最终在客户端对其进行解析以对其进行一些计算,则发送HTML是一种不好的做法。

  • 如果您最终要做的就是将JSON合并到页面的DOM树中,则发送JSON是不正确的做法。


3
如果您需要进行一些计算并将其合并到页面的DOM中该怎么办?
Enrique

我想知道,如果在方程式中加上“ 知识的半衰期 ”,那么上述陈述会附上真实性多长时间?
2014年

是否可以返回具有<script>标记的HTML,然后在加载页面时在客户端执行它们?
nish1013 '16

这个。同样,如果您返回的数据需要以某种方式在其表示中保持流畅,例如,如果您有一个HTML表格,其中包含您希望能够进行排序的列。不管您是否使它们现在可以排序,您都可能希望稍后再进行,因此在这种情况下,值得采用面向JSON的额外努力。
trpt4him

我还要补充一点,如果您只是想通过JSON请求图像url以尝试在页面上呈现它们,那么从一开始就将它们包含在HTML中的性能要好得多,这样图像就可以更早开始加载(在ajax回来之前) 。
FailedUnitTest,

30

好,

我是喜欢以这种方式分离事物的稀有人物之一:-服务器负责传递数据(模型);-客户负责显示(查看)和操作数据(模型);

因此,服务器应专注于交付模型(在这种情况下,JSON更好)。这样,您将获得一种灵活的方法。如果要更改模型的视图,则可以让服务器发送相同的数据,而只需更改将这些数据更改为视图的客户端,JavaScript组件。想象一下,您有一台服务器将数据传输到移动设备以及桌面应用程序。

此外,这种方法还可以提高生产率,因为可以同时构建服务器和客户端代码,而永远不会失去焦点,而这正是您不断从js切换到PHP / JAVA / etc时发生的情况。

通常,我认为大多数人都喜欢在服务器端尽可能多地执行操作,因为他们不掌握js,因此他们尝试尽可能地避免这样做。

基本上,我和在Angular上工作的人有相同的看法。我认为这是网络应用程序的未来。


是的,我完全同意你的看法。但是,当涉及到敏感信息时,我会做很多事情,我认为是最好的。如果您需要客户端根据结果做出不同的反应,我将使用json,否则将使用html。
Fi Horan

9

我想添加一些有趣的东西。我开发了一个只能加载一次完整视图的应用程序。从那时起,它仅使用ajax传递回服务器。它只需要加载一页(我的原因在这里并不重要)。有趣的是,我特别需要返回一些要在javascript中进行操作的数据以及要显示的局部视图。我本可以将其分为两个调用,分别调用两个单独的操作方法,但是我决定增加一些乐趣。

一探究竟:

public JsonResult MyJsonObject(string someData)
{
     return Json(new { SomeData = someData, PartialView = RenderPartialViewToString("JsonPartialView", null) }, JsonRequestBehavior.AllowGet);
}

您可能会问什么RenderPartialViewToString()?这就是这里的一点点酷:

protected string RenderPartialViewToString(string viewName, object model)
{
     ViewData.Model = model;

     using (StringWriter sw = new StringWriter())
     {
          ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
          ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
          viewResult.View.Render(viewContext, sw);

          return sw.GetStringBuilder().ToString();
     }
}

我尚未对此进行任何性能测试,因此我不确定它是否会比调用JsonResult的一种操作方法和ParticalViewResult的一种操作方法产生更多或更少的开销,但我仍然认为这很酷。它只是将部分视图序列化为字符串,并将其与Json一起作为其参数之一发送。然后,我使用JQuery接受该参数并将其拍打到适当的DOM节点中:)

让我知道您对我的混合动力车的看法!


1
在一个请求中发送渲染的视图和数据似乎有点多余。只是开个玩笑,如果您有能力执行客户端视图渲染,则最好将视图模板和数据作为单独的请求发送。它需要一个额外的请求,但仅一次,因为模板请求将被缓存以供后续请求使用。理想情况下,最好结合使用客户端视图和服务器端视图渲染,以便可以在服务器上构建页面并在浏览器中构建局部视图,但是如果仅实现服务器端视图渲染,这并不是一个坏方法。
Evan Plaice 2012年

8

如果响应不需要进一步的客户端处理,我认为HTML可以。发送JSON仅会强制您执行客户端处理。

另一方面,当我不想一次使用所有响应数据时,我使用JSON。例如,我有一系列的三个链式选择,其中一个的选定值确定哪些值将用于填充第二个,依此类推。


7

IMV,这完全是关于将数据与数据表示分离开来,但是我支持Pascal,这并不一定意味着这种分离只能跨越客户端/服务器边界。如果已经(在服务器上)具有这种分隔,并且只想向客户端显示某些内容,则是否发送回JSON并在客户端上对其进行后处理,或者只是发送回HTML,完全取决于您的需求。在一般情况下,说您“错误”地发回HTML太笼统了IMV声明。


6

JSON非常通用且轻巧。当我开始将其用作客户端模板解析器数据时,我发现了它的美。让我解释一下,在我以前在服务器端使用smarty和视图(产生高服务器负载)之前,现在我使用一些自定义的jquery函数,并且所有数据都使用客户端浏览器作为模板解析器在客户端呈现。它节省了服务器资源,另一方面,浏览器每天都在改进其J​​S引擎。因此,客户端解析的速度现在不再是一个重要的问题,而且,JSON对象通常很小,因此它们不会占用大量客户端资源。我宁愿为浏览器速度较慢的某些用户提供一个慢速网站,而不是因为服务器负载很大而为所有人提供慢速网站。

另一方面,从服务器发送纯数据,您可以将其从表示中提取出来,这样,如果明天您要更改它或将数据集成到另一个服务中,则可以轻松得多。

只是我的2美分。


以及如何在禁用JavaScript的情况下确保页面可读?
Vinko Vrsalovic

8
如果禁用了JS,那么您也将无法加载html。根据我的Google Analytics(分析)统计,对2.3%的用户禁用了JS。最好的解决方法是尝试取悦所有人。
迈克,

4
我同意麦克100%。试图取悦所有人都是不可能的,只会伤害您。如果用户正在关闭JS,那么到现在为止,许多网站都无法使用JS。
CHEV

1
由于Analytics(分析)使用Javascript追踪资料,您如何在Analytics(分析)中取得JavaScript统计资料?
尼克,

@Nick好问题,但我发现这一点:stackoverflow.com/questions/15265883/...
雷南卡瓦列里

6

如果您想要一个干净的解耦客户端(我认为这是最佳实践),那么让100%的javascript创建的DOM有意义。如果您构建的MVC客户端具有所有如何构建UI的全部知识,则您的用户会一次下载一个javascript文件,并将其缓存在客户端上。初始加载之后的所有请求均基于Ajax,并且仅返回数据。这种方法是我发现的最干净的方法,它为演示文稿提供了干净的独立封装。

然后,服务器端仅专注于传递数据。

因此,明天当产品要求您完全更改页面的设计时,您所做的全部更改就是创建DOM的源JS,但很可能会重用您已经存在的事件处理程序,并且服务器将被忽略,因为它100%与表示分离


1
我同意,您也可以为您的移动应用重复使用json。
2014年

这应该是被接受的答案-前6-7个单词简洁地回答了这个问题。
nicholaswmin

同意。返回数据(JSON)优于presentation(html)的优点是您现在拥有一个“免费” Web API,可以将其重新用于其他客户端,无论是移动设备还是对该应用程序中某些数据感兴趣的完全不同的应用程序以我的经验,在服务器端使用仅处理数据而不处理表示的简单Web框架通常会产生良好而简单的结果。现代浏览器和CPU是如此之快,以至于只有在特殊情况下,渲染才会成为瓶颈。最大的瓶颈主要是网络本身和数据库调用。
Beginner_

4

根据您的UI,您可能需要更新DOM中的两个(或更多)不同的元素。如果您的回复是HTML格式,那么您是否要解析该内容以找出问题所在?或者,您可以只使用JSON哈希。

您甚至可以将其组合,返回带有html数据的JSON :)

{ 'dom_ele_1' : '<p>My HTML part 1</p>', 'dome_ele_2' : '<div>Your payment has been received</div>' }

如果您最终要做的就是将JSON合并到页面的DOM树中,则发送JSON是不正确的做法……并且通过将JSON与HTML结合使用,您将使用这种糟糕的
做法

2

HTML具有许多冗余且未显示的数据,例如标签,样式表等。因此,与JSON数据相比,HTML的大小将更大,从而导致更多的下载和渲染时间,也将导致浏览器忙于渲染新数据。


1

通常,当您有一个JavaScript小部件从服务器请求信息时,例如,列表或树视图或自动完成功能,就完成了json的发送。这是我发送JSON的时间,因为它是将被解析和原始使用的数据。但是,如果仅显示HTML,则生成服务器端并将其显示在浏览器上的工作量要少得多。浏览器经过优化,可以使用innerHTML =“”将HTML直接插入dom中,因此您不会出错。


innerHTML历史上看,FWIW 比文档片段要慢得多:coderwall.com/p/o9ws2g/…
Nate Whittaker

0

我认为这取决于设计的结构,使用JSON比使用HTML更性感,但问题是如何处理它以便可以轻松维护。

例如,假设我的列表页面使用了整个网站的相同html /样式,我将编写全局函数来格式化HTML的那些部分,而我要做的就是将JSON对象传递给该函数。


0

在大多数情况下,HTML响应就足够了,除非您必须在客户端执行一些计算。


0

视情况而定。

有时,必须避免使用JSON。例如,当我们的程序员在js编程时遇到麻烦时。

我的经验告诉我:与内联JSON相比,更好地使用ajax服务。

js迟早会成为问题

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.