什么时候适合在前端进行计算?


21

我的团队正在开发一个基于WEB的财务应用程序,并且与一位同事存在争议,该将计算保留在哪里-纯粹在后端还是在前端?

简要说明:我们将Java(ZK,Spring)用于前端,将Progress 4gl用于后端。涉及数据库中一些核心数学和数据的计算都保存在后端,因此我不在谈论它们。我说的是用户输入值X,然后将其添加到值Y(在屏幕上显示),然后结果显示在字段Z中的情况。我的意思是,纯简单的jQuery-ish操作。

因此,这里的最佳做法是:

1)使用JavaScript添加值,该值可保存到后端和后端,然后在后端“保存时”验证它们?

2)将所有业务逻辑放在同一位置-因此将值带到后端并在那里进行计算?

3)在前端进行计算;然后将数据发送到后端,在那里进行验证,仅在结果有效且相等时才再次进行计算,然后将其显示给用户?

4)还有别的吗?

注意:我们在Java中进行了一些基本的验证,但与其他所有业务逻辑一样,大多数验证仍在后端。

通过重新计算后端中的所有内容来发送的数据增加不是问题(XML大小较小;服务器和带宽可以承受用户增加的操作量)。


1
经验法则:使用强类型语言时。

1
如果所有逻辑都在后端,则自动化单元测试将更加容易。如果90%必须在后端,而10%必须在后端,那么我将100%放在后端。
伊恩

3
@Ian:如果您可以很好地构建代码,也可以对前端代码进行自动化的单元测试。
Lie Ryan

1
经验法则:只要您可以摆脱它。
goldilocks

3
经验法则:假设用户正在入侵您的JavaScript并进行自己的计算。从安全角度来看,必须在后端进行计算。您也可以两者都做:JS可以提供​​更快的反馈,但是实际计数的计算是在服务器上完成的。

Answers:


36

与以往一样,此类决策涉及不同目标之间的权衡,其中一些目标相互冲突。

  • 效率会建议您在前端执行计算-既因为这样用户计算机消耗的功率更大,而服务器却消耗较少的功率,并且因为用户看到的反馈更快,从而改善了用户体验。

  • 安全性要求任何状态更改操作都不能依赖于客户端计算机中正在检查或计算的数据,因为客户端计算机可能处于恶意攻击者的控制之下。因此,您必须验证来自服务器端不受信任来源的任何内容。

  • 编程效率和可维护性建议您不要浪费相同的时间进行两次相同的计算。

从表面上看,这听起来似乎所有事情都必须在服务器端完成,但并非总是如此。如果您可以轻松地维护重复的代码(例如,通过从服务器端Java验证器自动生成javascript验证器),则重复计算可能是一个很好的解决方案。如果所涉及的数据都不重要,例如,如果用户只能欺骗自己而不是欺骗用户(如果他们操纵值),则不需要服务器端验证。如果您的响应时间是由完全不同的瓶颈为主,这样往返延迟不察觉,然后UX考虑是不是决定性的,等等。因此,你必须要考虑如何强大的每个这些压力的是在您的情况,并据此决定。


4
我想补充一下这Programming efficiency and maintainability suggests that you shouldn't do the same computation twice because of the wasted effort.是不正确的,因为前端的[1]验证可以向用户提供快速反馈,以便在需要时进行更正。[2]在后端进行验证的响应速度较慢,因此无法为用户提供进行校正的最佳机会。用户将需要等待并重做更多工作。因此,我认为这两个验证并不完全相同。
通知2014年

9
这不是我想要了解的内容-可维护性确实意味着“不要重复自己”,并且根据此原则,重复肯定是不好的。如果没有其他考虑,则不应这样做。它的仍然经常一个好主意,但事实是,因为它违背这一原则,即更好的可用性,通过快速周转等方面的考虑。
Kilian Foth,2014年

@randomA您误用了该原理,如果您意味着只需要在服务器上计算需要在服务器上验证的内容,因为如果返回给客户端的“服务器验证值”(或任何依赖于此的值)在发送回服务器的某个时刻,无论如何您都必须再次验证它 -无用。否则,您需要某种安全引用系统,但效率可能更低。我想说的是,如果您可以在客户端上进行计算,请在客户端上进行计算,但也请不要相信客户端告诉您的内容
goldilocks

@goldilocks您也用粗体表示的也是我所同意的,您必须在后端验证所有内容。我的观点是:前端验证的响应速度更快,因此与后端验证并不完全相同。
通知2014年

13

在后端进行计算有很强的理由

  • 业务逻辑不属于表示层
  • JavaScript中的业务逻辑构成威胁
  • 您假设存在一个前端->后端关系,但这种关系并不总是正确的,应该将后端视为能够或为多个前端应用程序提供服务,因此您不能承担任何责任。
  • 如果计算使用大量数据,将其保存在前端将不会有效
  • 如果计算使用数据库,则您将无法在前端复制数据库

我的建议

  • 让数据库强制执行模型中尽可能多的业务规则,包括外键,主键,检查约束和触发器
  • 不满足业务规则时让业务层引发异常(这是因为数据库返回了错误,或者是因为业务层本身已验证了数据)
  • 当且仅当响应时间不可接受时,才使用Ajax进行验证或预处理(该工作不会真正在JavaScript中完成,它将在后端完成而无需重新加载页面)
  • 您可以在JavaScript中进行简单的验证,例如不允许使用空值,不允许使用的值太长或超出范围(对于后者,您可能希望在后端生成范围)

2
数据库强制执行业务规则的问题是向前端报告违规!如果前端执行业务规则,则它可以快速将有意义的错误消息反馈给用户。如果后端这样做,则前端和后端之间会有很多笨拙的双向通信,因为一次报告一次错误。
James Anderson

@JamesAnderson不再是“前端”。同一数据库可以有多个前端,也可以有多个数据库到多个前端。同样,拥有后端强制执行业务规则并不意味着前端被禁止这样做。我在第二个要点中强调了这一点。
图兰斯·科尔多瓦
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.