【问题标题】:Ajax requests and racing conditions (client and server side)Ajax 请求和竞速条件(客户端和服务器端)
【发布时间】:2015-01-31 09:55: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 #2 是在Ajax request #1 之后被我们执行的。

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

【问题讨论】:

    标签: javascript php ajax race-condition


    【解决方案1】:

    您是否担心来自同一客户或多个客户的比赛条件?

    如果来自同一个客户端,我认为最安全的选择是在 ajax 请求中包含一个 unix 时间戳并将这个值记录在服务器上。如果请求附带的时间戳早于最后记录的值,则忽略该请求(或将警告发送回浏览器)。

    我不确定您将如何处理多个时钟不同步的客户端...

    【讨论】:

      【解决方案2】:

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

      例如:

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

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

      【讨论】:

        【解决方案3】:

        在服务器上:

        • 构建请求表以将请求 ID 映射到时间戳
        • 向服务器记录任何请求,希望所有请求都带有时间戳
        • 如果任何请求出现问题(例如位置 6 在 5 之前)
          • 检查请求表,如果是较早的请求(时间戳)则不处理请求并发送忽略标志
        • 如果它按顺序排列
          • 这很好,照常进行,无需发送任何忽略命令

        在客户端:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多