1

当 POST 数据时 - 无论是使用 AJAX 还是从移动设备或您拥有的设备 - 通常都会出现“重试”条件,因此如果出现超时等情况,数据会再次被 POST。

这真的是个好主意吗?

POST 数据是幂等的,所以如果你

  1. 向服务器发送 POST,
  2. 服务器收到请求,
  3. 需要时间来执行和
  4. 然后发回数据

如果在 3. 之后的某个时间达到超时,那么下一次重试将发送本应是幂等的数据。

那么问题是应该为 POST 数据设置重试(从客户端调用时),还是应该将服务器设计为始终适当地处理 POST 数据(使用令牌等),或者我错过了什么?

根据问题更新- 这是针对移动应用程序的。碰巧的是,在测试过程中发现超时太短,应用程序会重试。同时,后端服务器实际上已经接受并处理了初始请求,并在新的(否则相同的)重新请求进来时感到不安。

4

4 回答 4

1

nonce是对此的(部分)解决方案。服务器生成一个随机数并将其提供给客户端。客户端发送POST包含nonce的信息,服务器检查nonce是否有效且未使用,如果是,则对nonce进行操作POST并使nonce无效,如果不是,则报告nonce已使用并丢弃数据。通过用户单击提交按钮两次来避免“双重发布”问题也非常有用。

但是,它将问题从客户端转移到服务器上的另一个问题。如果您在操作之前使 nonce 无效,则该操作可能仍会失败/挂起,如果您在之后使其无效,则 nonce 在处理期间对请求仍然有效。因此,服务器上的一个可能场景变成了接收。

  1. 锁定随机数
  2. 采取行动
  3. 在阻止操作完成的任何处理错误时,回滚,释放随机数锁定。
  4. 如果没有错误,则无效/删除 nonce。

服务器端的信号量对此最有帮助,大多数后端语言都有用于这些的库。

因此,实现所有这些:

  1. 重试是安全的,如果该操作已经执行,则不会再次执行。
  2. nonce 已被使用的回复可以理解为对原始 POST 已被执行的确认。
  3. 如果您需要第二个请求显示第一个请求通过的操作的结果,那么服务器端将需要一个短期缓存。
  4. 由您来设置后续尝试的合理限制(如果第二次失败怎么办?或第三次?)。
于 2013-09-18T19:48:45.687 回答
0

自动重试的问题是服务器需要知道先前的 POST 是否已成功处理以避免意外后果。例如,如果每次 POST 插入一条 DB 记录,但插入后最后一次 POST 超时,自动重新 POST 会导致重复的 DB 记录,这可能不是您想要的。

在健壮的设置中,您可能能够发现超时并回滚任何已发布的更新。这将安全地允许自动重新发布。但是许多(大多数?)网络系统并没有这么复杂,因此您通常需要人工干预来确定 POST 是否应该再次发生。

于 2013-09-18T19:29:27.523 回答
0

如果您的请求失败到足以引发这样的事情,那么您将遇到与实施重试条件无关的重大问题。我从未见过需要这种功能的 Web 应用程序。将您的应用程序编程为使用 F5 锤子自动击败过载的服务器并不是解决任何问题的方法。

如果此 ajax 请求是通过单击按钮触发的,请禁用该按钮直到它返回,无论成功与否。如果失败,让用户再次单击它。

于 2013-09-18T20:48:36.660 回答
0

如果您无法避免长时间等待服务器响应,更好的做法是返回立即响应(带有消息“处理”的 200OK)并让客户端稍后发送一个新请求以检查操作是否进行了。

AJAX 并非旨在以这种方式使用(“重”操作)。顺便说一句,默认的 HTTP 超时是 7200 秒,所以我认为您不会轻易达到它 - 但无论如何,您应该避免让用户等待很长时间。

提供有关该过程的更多信息(例如您正在尝试做什么)将有助于建议避免此类障碍的方法。

于 2013-09-18T19:37:35.603 回答