【问题标题】: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 使用时间戳的建议。