【问题标题】:Client-side logic OR Server-side logic?客户端逻辑还是服务器端逻辑?
【发布时间】:2010-12-03 18:19:13
【问题描述】:

我做过一些基于网络的项目,我遇到的大部分困难(问题、困惑)都可以在帮助下解决。但是,即使在询问了一些经验丰富的开发人员之后,我仍然有一个重要的问题:什么时候可以同时使用服务器端代码和客户端脚本 (JavaScript) 来实现功能,应该首选哪一个? p>

一个简单的例子:

要呈现动态 html 页面,我可以在服务器端代码(PHP、python)中格式化页面,并使用 Ajax 获取格式化页面并直接呈现(服务器端逻辑更多,客户端逻辑更少)。

我还可以使用 Ajax 来获取数据(未格式化,JSON)并使用客户端脚本来格式化页面并通过更多处理来呈现它(服务器从数据库或其他来源获取数据,并返回它使用 JSON 或 XML 发送到客户端。客户端的逻辑更多,服务器端的逻辑更少)。

那么我该如何决定哪一个更好呢?哪一个提供更好的性能?为什么?哪个更人性化?

随着浏览器 JS 引擎的发展,JS 可以在更短的时间内被解释,所以我应该更喜欢客户端脚本吗?

另一方面,随着硬件的发展,服务器性能不断提高,服务器端逻辑的成本会降低,那么我应该更喜欢服务器端脚本吗?

编辑:

有了答案,我想做一个简短的总结。

客户端逻辑的优点:

  1. 更好的用户体验(更快)。
  2. 网络带宽更少(成本更低)。
  3. 提高可扩展性(减少服务器负载)。

服务器端逻辑的优点:

  1. 安全问题。
  2. 更好的可用性和可访问性(移动设备和旧浏览器)。
  3. 更好的 SEO。
  4. 易于扩展(可以添加更多服务器,但不能使浏览器更快)。

在面对特定场景时,我们似乎需要平衡这两种方法。但是怎么做?最佳做法是什么?

我将使用客户端逻辑,但以下情况除外:

  1. 安全至关重要。
  2. 特殊组(禁用 JavaScript、移动设备等)。

【问题讨论】:

    标签: performance


    【解决方案1】:

    在很多情况下,恐怕最好的答案是两者都

    正如 Ricebowl 所说,永远不要相信客户。但是,我觉得如果您确实信任客户,这几乎总是一个问题。如果您的应用程序值得编写,则值得妥善保护。如果有人可以通过编写自己的客户端并传递您不期望的数据来破坏它,那是一件坏事。因此,您需要在服务器上进行验证。

    不幸的是,如果您验证服务器上的所有内容,这通常会给用户带来糟糕的用户体验。他们可能在填写表格时发现他们输入的一些内容不正确。这可能适用于“互联网 1.0”,但人们对当今互联网的期望更高。

    这可能会让您编写大量冗余代码,并在两个或多个位置进行维护(一些定义,例如最大长度也需要在数据层中维护)。对于相当大的应用程序,我倾向于使用代码生成来解决这个问题。我个人使用 UML 建模工具(Sparx System 的 Enterprise Architect)对系统的“输入规则”进行建模,然后使用部分类(我通常在 .NET 中工作)来生成验证逻辑的代码。您可以通过以 XML 等格式对规则进行编码并在客户端和服务器层上从该 XML 文件(输入长度​​、输入掩码等)派生一些检查来实现类似的事情。

    可能不是你想听到的,但如果你想把它做好,你需要在两个层次上都执行规则。

    【讨论】:

    • +1;我从没想过要批评 OP 问题中的错误二分法(这个那个)。
    • +1 两者兼而有之:您想要客户端端的用户体验和性能优势,但需要服务器端的安全和控制。
    • 是的,埃里克,我几乎同意你的看法。但是什么是最佳实践?我该如何平衡这两种方法?如何通过指南将每种方法应用于不同的场景?指南是什么?谢谢。
    • @Tower:你不会找到单一的最佳实践,因为每个应用程序都有自己的威胁模型(暴露于黑客攻击的可能性和成功的可能性)以及它自己的用户期望。如果威胁级别“高”,您必须实施服务器端检查。我使用空中报价是因为我开发的几乎每个应用程序都属于“高”类别。如果用户期望值高到需要立即验证,您必须这样做(或面对不满意用户的前景)。您需要为自己的应用确定每个变量。
    【解决方案2】:

    我倾向于更喜欢服务器端逻辑。我的理由很简单:

    1. 我不信任客户;这可能是一个真正的问题,也可能不是,但这是习惯性的
    2. 服务器端减少了每笔交易的数量(尽管它确实增加了交易的数量)
    3. 服务器端意味着我可以相当确定正在发生什么逻辑(我不必担心客户端浏览器可用的 Javascript 引擎)

    可能还有更多更好的理由,但这些是我现在最关心的。如果我想到更多,我会添加它们,或者在我做之前对提出它们的人进行投票。


    已编辑,valya cmets 使用客户端逻辑(使用 Ajax/JSON)允许(更容易)创建 API。这很可能是真的,但我只能同意一半(这就是为什么我还没有对这个答案投赞成票的原因)。

    我对服务器端逻辑的概念是检索数据并组织它;如果我做对了,那么逻辑就是“控制器”(MVC 中的 C)。然后将其传递给“视图”。我倾向于使用控制器来获取数据,然后“视图”处理将其呈现给用户/客户端。所以我不认为客户端/服务器的区别与创建 API 的论点必然相关,基本上:课程的马。 :)

    ...另外,作为一个业余爱好者,我承认我对 MVC 的使用可能略有曲解,所以我愿意在这一点上予以纠正。但我仍然将演示文稿与逻辑分开。就 API 而言,这种分离是加分项。

    【讨论】:

    • 有趣的是,我得到了四个赞成票和一个反对票;如果投反对票的人会/可以解释,我会感兴趣吗?这样,答案就变得错误更少,或者更有用
    • 我没有投反对票(没有解释的路过投反对票也让我很恼火),但我猜这是因为验证客户端和服务器端都很重要。
    • 很好的解释,点赞。只是作为咨询,根据你的解释,你更喜欢I go with my current algorithm?
    【解决方案3】:

    我通常会尽可能多地实现合理的客户端。让我进入服务器端的唯一例外是解决以下问题:

    信任问题

    任何人都能够调试 JavaScript 和读取密码等。这里不用多想。

    性能问题

    JavaScript 引擎发展迅速,因此这已不再是一个问题,但我们仍处于 IE 主导的世界中,因此当您处理大量数据集时,事情变慢。

    语言问题

    JavaScript 是弱类型语言,它对你的代码做了很多假设。这可能会导致您使用令人毛骨悚然的解决方法,以使事情在某些浏览器上以应有的方式工作。我避免像瘟疫这样的事情。


    从您的问题来看,听起来您只是想将值加载到表单中。除非出现上述任何问题,否则您有 3 个选择:

    纯客户端

    缺点是您的用户加载时间会加倍(一次加载空白表单,另一次加载数据)。但是,对表单的后续更新将不需要刷新页面。如果从服务器获取大量数据加载到同一个表单中,用户会喜欢这样。

    纯服务器端

    优点是您的页面会加载数据。但是,对数据的后续更新将需要刷新页面的所有/重要部分。

    服务器-客户端混合

    您将两全其美,但是您需要创建两个数据提取点,这会导致您的代码略微膨胀。

    每个选项都需要权衡取舍,因此您必须权衡它们并决定哪个选项能给您带来最大的好处。

    【讨论】:

    • Microsoft 的 MVC 框架允许您编写一次代码(实际上,通常只为大多数标准验证的属性添加属性)并获得客户端和服务器端验证,而无需编写额外代码。对于其他语言/平台,我过去曾编写过代码生成器,可根据元数据创建客户端和服务器端验证。
    【解决方案4】:

    我没有听说过的一个考虑因素是网络带宽。举一个具体的例子,我参与的一个应用程序都是在服务器端完成的,结果是 200Mb 的网页被发送到客户端(如果不对一堆应用程序进行重大的重大重新设计,就不可能少做);导致 2-5 分钟的页面加载时间。

    当我们通过从服务器发送 JSON 编码的数据并让本地 JS 生成页面来重新实现这一点时,主要好处是发送的数据缩小到 20Mb,从而导致:

    • HTTP 响应大小:200Mb+ => 20Mb+(相应的带宽节省!)

    • 加载页面的时间:2-5 分钟 => 20 秒(其中 10-15 秒被进一步优化的数据库查询占用)。

    • IE 进程大小:200MB+ => 80MB+

    请注意,最后两点主要是因为服务器端必须使用糟糕的表内表树实现,而客户端允许我们重新设计视图层以使用更轻量级的页面。但我的主要观点是节省网络带宽。

    【讨论】:

      【解决方案5】:

      我构建了一个 RESTful Web 应用程序,其中所有 CRUD 功能在没有 JavaScript 的情况下可用,换句话说,所有 AJAX 效果都是严格的渐进式增强

      我相信只要有足够的奉献精神,大多数 Web 应用程序都可以这样设计,从而消除您的问题中提出的许多服务器逻辑与客户端逻辑“差异”,例如安全性、可扩展性,因为在这两种情况下,请求都是路由到同一个控制器,其中的业务逻辑都是相同的,直到最后一英里,其中为那些 XHR 返回的是 JSON/XML,而不是完整的页面 HTML。

      只有在 AJAXified 应用程序比其静态应用程序先进得多的少数情况下,GMail 是我想到的最佳示例,然后需要创建两个版本并将它们完全分开(向 Google 致敬!)。

      【讨论】:

      • 我真的不明白为什么还有人为不支持 JavaScript 的浏览器而烦恼。自 Netscape 2.0 以来的任何浏览器中都有 JS - 你知道还有谁还在使用 Mosaic 或 Links 吗?
      • 网络不只是浏览器,别忘了网络服务。如果您不经常让自己意识到为整个网络构建通用应用程序,那么很容易过度依赖 JS,并在非人类敲门时发现自己毫无准备。
      • Jerry - 这是一个完全不同的讨论,但你能举一个真实的例子吗?我的意思是,Web 服务提供 HTTP API,而不是 HTML 网页,AFAIK。
      【解决方案6】:

      我想在这个问题上给我两分钱。

      我通常支持服务器端方法,原因如下。

      • 对 SEO 更友好。 Google 无法执行 Javascript,因此所有这些内容对搜索引擎都是不可见的
      • 性能更可控。由于您几乎完全依赖用户的浏览器和机器来呈现事物,因此 SOA 的用户体验始终是可变的。即使您的服务器可能运行良好,但机器速度较慢的用户仍会认为您的网站是罪魁祸首。
      • 可以说,服务器端方法更易于维护和阅读。

      我已经使用这两种方法编写了几个系统,根据我的经验,服务器端是一种方式。但是,这并不是说我不使用 AJAX。我构建的所有现代系统都包含这两个组件。

      希望这会有所帮助。

      【讨论】:

        【解决方案7】:

        在这个阶段,客户端技术处于领先地位,随着 Backbone、Knockout、Spine 等许多客户端库的出现,以及 JSrender、mustache 等客户端模板的加入,客户端开发变得更加容易. 所以,如果我的要求是去交互式应用程序,我肯定会去客户端。 如果您有更多静态 html 内容,那么可以选择服务器端。 我用两者做了一些实验,我必须说服务器端比客户端更容易实现。 就性能而言。阅读本文,您将了解服务器端性能得分。 http://engineering.twitter.com/2012/05/improving-performance-on-twittercom.html

        【讨论】:

          【解决方案8】:

          我知道这篇文章很旧,但我想发表评论。

          根据我的经验,最好的方法是结合使用客户端和服务器端。是的,Angular JS 和类似的框架现在很流行,它们使开发轻量级、提高性能并在大多数 Web 服务器上工作的 Web 应用程序变得更加容易。但是,企业应用程序的主要要求是在一页上显示可以包含 500 多条记录的报告数据。对于返回大量数据列表的页面,用户通常需要能够使这个庞大的列表易于过滤、搜索和执行其他交互功能的功能。因为 IE 11 和更早的 IE 浏览器是大多数公司的“首选浏览器”,所以您必须注意这些浏览器在使用现代 JavaScript、HTML5 和 CSS3 时仍然存在兼容性问题。通常,要求是使站点或应用程序在所有浏览器上兼容。这需要添加 shiv 或使用原型,其中包含用于创建客户端应用程序的代码,增加了浏览器上的页面负载。

          所有这些都会降低性能,并可能导致可怕的 IE 错误“此页面上的脚本导致 Internet Explorer 运行缓慢”,迫使用户选择是否要继续运行脚本...造成错误用户体验。

          根据用户对现有应用程序的偏好,确定应用程序的复杂性以及用户现在想要什么以及将来可能想要什么。如果这是一个包含中小型数据的简单网站或应用程序,请使用 JavaScript 框架。但是,如果他们想加入可访问性;搜索引擎优化;或者需要显示大量数据,使用服务器端代码来渲染数据和客户端代码。在这两种情况下,请使用 Fiddler 或 Chrome 开发人员工具等工具来检查页面加载和响应时间,并使用最佳实践来优化代码。

          签出使用 ASP.NET Core 开发的 MVC 应用。

          【讨论】:

            【解决方案9】:

            我认为第二种变体更好。例如,如果您稍后实现“皮肤”之类的东西,您会感谢自己没有在服务器上格式化 html :)

            它还保持了视图和控制器之间的区别。 Ajax 数据通常由控制器产生,所以让它只返回数据,而不是 html。

            如果您稍后要创建 API,则需要对代码进行少量更改

            此外,我认为“裸”数据比 HTML 更易于缓存。例如,如果您为链接添加一些样式,则需要重新格式化所有 html.. 或在您的 js 中添加一行。而且它没有html那么大(以字节为单位)。

            但是如果需要大量繁重的脚本来格式化数据,那么让用户的浏览器来格式化就不是很酷了。

            【讨论】:

              【解决方案10】:

              只要您不需要向客户端发送大量数据以允许其完成工作,客户端将为您提供更具可扩展性的系统,因为您将负载分配给客户端而不是锤击你的服务器来做所有事情。

              另一方面,如果您需要处理大量数据以生成少量 html 发送给客户端,或者如果可以进行优化以使用服务器的工作同时支持多个客户端(例如进程数据一次并将生成的 html 发送给所有客户端),那么它可能更有效地利用资源在服务器上完成工作。

              【讨论】:

              • 但随后有人可以编写自己的客户端,并为系统提供他们想要的任何数据……无需任何验证。
              • 是的,在某些情况下可能需要考虑。但是问题没有提到“安全关键”数据,它只是说“如果我可以实现它,ss 或 cs,哪个更好?”,对此我给出了一个笼统的答案。
              【解决方案11】:

              如果你在 Ajax 中这样做:

              您必须考虑残疾人的可访问性问题(在 google 中搜索网络可访问性),以及旧浏览器、没有 JavaScript、机器人(如 google bot)等的人。

              如果您从未经常使用 JavaScript,那么您将不得不考虑“渐进式增强”,这并不容易。简而言之,您必须让您的应用在旧浏览器和那些没有 JavaScript 的浏览器(例如某些移动设备)上运行,或者如果它被禁用。

              但如果时间和金钱不是问题,我会选择渐进式增强。

              但也要考虑“后退按钮”。当我浏览一个 100% AJAX 网站时,我讨厌它让你的后退按钮无用。

              祝你好运!

              【讨论】:

                【解决方案12】:

                2018 年的答案,有 Node.js 的存在

                由于 Node.js 允许您在服务器上部署 Javascript 逻辑,您现在可以在服务器端和客户端重复使用验证。

                确保您设置或重组数据,以便您可以在不更改任何代码的情况下重复使用验证。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2015-08-14
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-03-14
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多