Ajax请求和竞赛条件(客户端和服务器端)

Ajax requests and racing conditions (client and server side)

本文关键字:客户端 服务器端 条件 请求 求和 竞赛 Ajax      更新时间:2023-09-26

让我们想象一下这样一种情况:我们一个接一个地向服务器发送了两个相似(几乎相似)的异步ajax请求。由于网络延迟,第二个请求在第一个请求之前执行。

Ajax request #1: /change/?object_id=1&position=5
Ajax request #2: /change/?object_id=1&position=6

结果,我们将object_id=1的位置设置为position=5,但我们想要position=6,因为我们在Ajax request #1之后执行了Ajax request #2

在服务器端和客户端避免这种情况的最佳实践是什么?

您是否担心来自同一个客户端或来自多个客户端的竞速条件?

如果来自同一个客户端,我认为最安全的做法是在ajax请求中包含unix时间戳,并将该值记录在服务器上。如果请求的时间戳比上次记录的值早,忽略该请求(或向浏览器发送警告)。

对于这种情况,我通常在成功处理程序中添加一个检查,以确保返回的值仍然是我想要的值。这将需要在结果对象中发送您正在搜索的参数。

例如:

var query = $('input').val();
$.get('/search', { query: query }, function(res) {
  if(res.query == $('input').val()) {
    //show search results
  }
});

我不知道你用例的细节,但是这个通用模式应该会有帮助。

服务器端:

  • 创建一个请求表,将请求id映射到时间戳
  • 记录任何请求到服务器,期望所有请求都带有时间戳
  • 如果任何请求顺序错误(例如位置6在位置5之前)
    • 检查请求表,如果它是一个较早的请求(时间戳),那么不处理请求并发送一个忽略标志
  • 如果它是有序的
    • 这很好,照常进行,不需要发送任何忽略订单

客户端:

  • 当请求返回时,检查忽略标志。如果有的话。不要对客户端做任何事情
  • 否则照常处理数据

请注意,我建议的这个实现要求您来回发送数据(如JSON),而不是表示代码(如HTML片段),因为您需要在客户端检查忽略标志。

这个答案类似于@Farray建议使用时间戳。