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

发布于 2024-12-03 04:04:12 字数 409 浏览 0 评论 0原文

让我们想象一下这样的情况:我们一一向服务器发送了两个相似(几乎相似)的异步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 请求 #2 是在我们的 Ajax request #1 之后执行的。

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

Let's imagine the situation that we've sent two similar (almost similar) async ajax requests to server one by one. Because of lag in network, the second request was executed before first request.

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

In result, we have object_id=1 position set to position=5, but we want position=6 because Ajax request #2 was executed after Ajax request #1 by us.

What is the best practice to avoid this on server side and client side?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

刘备忘录 2024-12-10 04:04:12

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

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

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

Are you worried about racing conditions from the same client or from multiple clients?

If from the same client, I would think the safest bet would be to include a unix timestamp in the ajax request and log this value on the server. If a request comes with a timestamp that is older than the last logged value, ignore the request (or send a warning back to the browser).

I'm not sure how you would handle multiple clients with unsynchronized clocks...

深居我梦 2024-12-10 04:04:12

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

例如:

var query = $('input').val();

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

我不知道您的用例的详细信息,但这个一般模式应该有所帮助。

For situations like this, I usually put a check in my success handler to make sure that the value being returned is still the one that I want. This will require sending up the parameter you're searching across in the results object.

For example:

var query = $('input').val();

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

I don't know the particulars of your use case, but this general pattern should help.

飘过的浮云 2024-12-10 04:04:12

在服务器上:

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

在客户端:

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

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

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

On the server :

  • Build a request table to map request id to timestamp
  • Log any request to the server, expect all requests come with timestamp
  • If any request comes out of order (e.g. position 6 comes before 5)
    • Check the request table, if it is an earlier request (timestamp) then do not process the request and send an ignore flag
  • If it comes in order
    • This is fine, proceed as usual and no need to send any ignore order

On the client:

  • When request comes back in, check the ignore flag. If it is there. Don't do anything to the client
  • Otherwise proceed as usual by processing the data

Note that this implementation that I suggested requires you to send back and forth data (such as JSON) and not the presentation code (such as HTML fragment) as you would need to check for the ignore flag on the client side.

This answer is similar to what @Farray suggestion of using timestamp.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文