隐藏的AJAX请求伪造性能有多安全?


48

什么是隐藏的AJAX请求?

我注意到,旨在使用户操作立即发生的隐藏AJAX请求的使用率有所增加。我将这种类型的AJAX请求称为非阻塞。这是一个AJAX请求,用户没有意识到它正在发生,它是在后台执行的,它的操作是无声的(没有冗长的指示AJAX调用已成功完成)。目的是使操作看起来确实在尚未真正完成时立即发生。

这是非阻塞AJAX请求的示例;

  • 用户单击电子邮件集合上的删除。这些项目会立即从其收件箱中消失,并且可以继续进行其他操作。同时,AJAX请求正在后台处理项目的删除。
  • 用户填写新记录表格。单击保存。新项目将立即显示在列表中。用户可以继续添加新记录。

为了澄清起见,下面是阻止AJAX请求的示例;

  • 用户单击电子邮件集合上的删除。出现沙漏光标。发出AJAX请求,并在响应时关闭沙漏光标。用户必须等待一秒钟才能完成操作。
  • 用户填写新记录表格。单击保存。带有AJAX加载程序动画的表格会变成灰色。显示一条消息“您的数据已保存”,新记录出现在列表中。

上述两种情况之间的区别在于,非阻塞AJAX设置不提供操作执行的反馈,而阻塞AJAX设置提供。

隐藏的AJAX请求的风险

此类AJAX请求的最大风险是,当AJAX请求失败时,Web应用程序可能处于完全不同的状态。

例如,一个非阻塞示例;

  • 用户选择一堆电子邮件。单击删除按钮。该操作似乎立即发生(项目从列表中消失)。然后,用户单击“撰写”按钮,并开始输入新电子邮件。这时JavaScript代码发现AJAX请求失败。该脚本可能会显示错误消息,但目前确实没有意义。

或者,一个阻塞的例子;

  • 用户选择一堆电子邮件。单击删除按钮。看到一个沙漏,但是操作失败。他们收到一条错误消息,说“错误。等等等等”。它们将返回到电子邮件列表,并且仍然具有要删除的电子邮件。他们可以尝试再次删除它们。

执行非阻塞AJAX请求还存在其他技术风险。用户可以关闭浏览器,可以导航到另一个网站,并且他们可以导航到当前网络中的另一个位置,这使得任何错误响应的上下文都变得毫无意义。

那么为什么它变得如此受欢迎?

Facebook,Google,Microsoft等。等等。所有这些大型域越来越多地使用非阻塞AJAX请求来使操作看起来像是立即执行的。我还看到没有保存或提交按钮的表单编辑器有所增加。离开字段或按Enter键。该值已保存。没有您的个人资料已更新消息或保存步骤。

AJAX请求不是确定的,在完成之前不应被视为成功,但是许多主要的Web应用程序正像这样运行。

这些使用非阻塞性AJAX调用来模拟响应式应用程序的网站是否冒着快速出现的代价冒着不必要的风险?

为了保持竞争力,我们所有人都应该遵循这种设计模式吗?


20
通过以下事实可以证明这一点:成功操作的可能性更大,因此,为了避免罕见的过度乐观反馈而缓慢进行是一个不好的权衡。转变为人际关系,您是愿意与一个冷静,阳光明媚的人互动,还是断然认为一切可能出错的人都会出错并采取相应行动?
Kilian Foth,

1
对我来说,我正在努力的是,桌面应用程序同时具有操作和错误发生的功能。在Web应用程序中,操作会立即发生,但错误会滞后。但是,站点的运行与桌面应用程序的设计有关。
Reactgular 2013年

7
您是否还考虑过当桌面应用程序写入磁盘,实际上将其放入OS缓冲区以及磁盘发生故障而无法将其写入磁盘时会发生什么情况?或者,就此而言,将字节写入磁盘后,磁盘将发生故障。在这两种情况下,用户认为某件事确实发生了,而实际上却没有。
2013年

2
@KilianFoth我更愿意假设一切都会出错的人,如果“阳光灿烂”的人会在遇到麻烦的第一个迹象时猛击你并偷走你的钱包。因此,这取决于页面对失败的反应程度。
Izkata

1
@ButtleButkus我认为这些保存的消息是新的。当我问这个问题时,他们不在那儿。我注意到Google最近添加了更多反馈,这是它在后台执行操作。
Reactgular 2014年

Answers:


62

与其说是真正的响应能力,不如说是“假”性能。受欢迎的原因有很多:

  • 如今,互联网连接相当可靠。AJAX请求失败的风险非常低。
  • 所执行的操作并不是真正的安全关键。如果您的电子邮件没有在服务器上被删除,则最糟糕的情况是您下次访问该页面时必须再次将其删除。
  • 您可以将页面设计为在请求失败时撤消操作,但实际上不必那么微妙,因为这意味着您与服务器的连接已断开。说“连接断开。无法保存最近的更改。请稍后再试”。
  • 您可以将页面设计为仅允许一个待处理的AJAX请求,这样您的状态就不会与服务器过于同步。
  • 如果在AJAX请求待处理时尝试关闭页面或离开页面,浏览器会警告您。

AJAX待处理警告


8
最后一点,所有浏览器默认都这样做吗?
2013年

我不知道。我只在IE9和最新版的chrome上进行了测试。
卡尔比勒费尔特

3
您显然不熟悉澳大利亚的互联网,更不用说贫穷,发展中和孤立的地方,甚至不能在行驶中的车辆上移动……
hippietrail

2
@hippietrail好吧,您不能一直让所有人开心。
KOVIKO

1
用户发送请求时,他并不总是要求新页面。我认为,精心设计的AJAX应用程序可以使它们更有趣,让用户比重新加载更有效地了解正在发生的事情。
Frederik.L 2014年

32

假设某些事情可以正常工作并在远程发生故障时显示错误,则比阻止用户在服务器做出响应之前不能执行任何其他操作更为用户友好。

电子邮件客户端实际上是一个很好的例子:当我有一个包含5封电子邮件的列表,并且选择了顶部的电子邮件时,我希望当点击DEL3次时,前三封电子邮件会被删除。使用“非阻止AJAX”,此功能可以正常工作-每次我按下该键时,所选电子邮件便会立即删除。如果出现问题,将显示错误,并再次显示未正确删除的电子邮件,或者重新加载页面以摆脱不一致的本地状态。

因此,在最常见的情况下(即成功),它可以提高可用性。在极少数情况下 -故障-可用性降低(删除的元素再次显示或应用程序“重新启动”),但是在创建应用程序时,通常希望在常见情况下(而不是在出现错误的情况下)具有最佳可用性。


1
+1这是问题的核心。如今,默认情况下人们会实施很多安全措施,以至于在最坏的情况下,您仍然不会冒着真正的用户错误的风险:想象电子邮件客户端无法删除,现在的本地状态很差,然后他们尝试删除未对齐的电子邮件4使用该服务器,绝大多数后端开发人员都将获得安全保障,以确保仅删除用户绝对想要的内容,因此这种未对齐不会导致错误的删除(它可能会出错但不会删除) 。
2013年

@JimmyHoffa,您将在删除请求中使用唯一的电子邮件ID。根据收件箱中电子邮件的任意显示顺序发送删除请求确实很糟糕。
Buttle Butkus 2014年

14

用户不在乎您的软件在幕后做什么:他们希望自己的行为具有可见的影响,并能够按照自己的节奏工作。

如果在客户端成功执行某项操作(例如删除电子邮件),则在服务器端也要使其成功。为什么删除失败?如果是由于某种限制(例如,您无法删除已存档的电子邮件),则应操作失败之前让用户知道该情况。

如果错误是由更严重的情况引起的(例如数据库崩溃),则应该有一种方法可以保存该操作,并在系统再次启动时重试该操作。

管理此聊天的一个很好的例子是Facebook处理聊天的方式。无法阻止用户突然断开连接,这意味着他们在离开之前将无法阅读您发送的消息。系统不会显示错误,而是会保存所有这些消息,并在用户回来时将其提供给用户。没有数据丢失。


2
+1。优秀的示例聊天。大多数用户希望他们的消息可以立即提供给所有人,并且由于此类消息很少失败,因此给用户一种幻想,那就是事实。
尼尔

1
@Niphra,“为什么删除失败?” 网络可能会由于许多原因而失败,而这与您的应用程序无关。有没有什么可以做,以制止。
Pacerier

5

您可以在两个选项之间折衷。例如,如果用户删除了一封电子邮件,则可以将其标记为红色或灰色,直到从服务器收到确认为止,然后才将其从列表中删除。在一个操作挂起时,用户仍然可以执行其他操作,因此它没有被阻止,但是仍然向用户提醒了他们的操作尚未提交。

Amazon AWS采用这种方法:当您停止/启动实例时,允许您选择它的复选框将变成微调框(因此,您几秒钟不能对其执行任何操作),但这不会阻止您与其他实例进行交互。


您的建议类似于XHR进行时gmail显示“ Saving ...”文本,完成后显示“ Saved”。如果总是说“已保存”,谁会相信呢?
Buttle Butkus 2014年

3

我认为,与更传统的网站相比,越来越多的网站试图像应用程序一样表现并在浏览器中进行更多处理(例如验证表单数据)。只要您的代码是可靠的,并且您可以期望它在正常情况下能够成功,我就不会觉得有太多问题。

您说:“这是JavaScript代码发现AJAX请求失败。脚本可能显示错误消息,但实际上这毫无意义。”

为什么没有意义?您可以返回到电子邮件列表,然后再次删除。为什么要等呢?实际上并没有太多的“风险”,它们并没有“显得”很快,它们实际上工作得更快。那么,如果活动不是“关键的”,为什么要慢呢?


1
也许毫无意义不是正确的词,但是我的意思是错误消息缺乏相对的上下文,因为用户现在正在做的事情完全不同。我想说的是,对于一个无知的网络用户,他们认为电子邮件确实成功删除了。因此,为什么现在以后,他们收到一条关于“锯”掉的东西的错误消息。对于我们的程序员来说,我们理解,但是对于使用gmail的爷爷,他们却不理解。
Reactgular 2013年

与应用程序每次更改值冻结一秒钟的应用程序相比,大多数人宁愿使用会立即发生事情,系统具有响应能力且在错误发生时UI可能以奇怪方式更新的10,000的应用程序中,有10,000的几率。

1

我的2c是:在某些情况下,最好像您所说的那样,“无阻塞”的Ajax操作以及其他一些不好的设计选择。示例:投票YouTube视频。当您单击那里的小开始时,您真的不希望页面的任何部分被阻止。最好默默地失败。即使是确认消息,也可能会导致过大的损失。但是,您删除电子邮件的示例符合阻止类型Ajax请求的强制要求。

Mongo DB会执行类似的操作(这可以视为桌面应用程序示例)。他们的操作有各种各样的“写问题”,您可以为每个操作将其配置为不同的值,范围从“立即返回并且不等待任何内容”到“阻止,直到您确认成功进行网络传输和然后返回”为“等到返回之前将内容正确安排到远程计算机上的磁盘写入中”。显然,如果您使用Mongo驱动程序制作桌面胖客户端(如C ++),则将对“关键性”最小的数据库操作(例如检查新电子邮件)设置最轻的写关注,而对更严格的写关注进行设置。

尽管我看到了非阻塞性Ajax的有用性,但我确实同意您的看法,它发生的太多了。至少有一个著名的“社交网络”站点可以将其用于照片上传。您选择了要上传的照片,然后bam,马上就会告诉您已完成,然后在第二天确定要添加更多照片(或使用您认为已经添加的照片)时就足够确定了,永远找不到。后来他们放弃了,实际上花了一些时间等待响应(实际上,有时您会收到诸如“无法上传照片,请稍后再试”之类的消息)。


+1以自己的方式看事物:)。上传照片是失败的一个很好的例子。
Reactgular

1
为什么最好选择阻止上传?在Picasa(网络界面)中,您可以将照片拖入其中,而在后台上传照片时,可以拖入更多照片或标记完成的照片,等等。阻止上传操作将使用户体验非常糟糕
BLSully
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.