同时链接点击和异步AJAX请求期间的竞争条件?

时间:2015-08-03 23:19:00

标签: javascript jquery ajax

我目前面临的情况类似于下面显示的相对简单的示例。当用户单击指向第三方域的链接时,我需要捕获用户DOM中存在的某些特征,并将该数据存储在我的服务器上。至关重要的是,我为所有支持JS的用户捕获这些数据,没有数据丢失。

我有点担心我目前的实施(如下所示)可能会有问题。如果外部目标服务器速度极快(或我的内部/save-outbound-link-data端点非常慢)会发生什么情况,并且在内部AJAX请求有足够时间完成之前处理了用户访问外部链接的请求?我不认为这会是一个问题(因为在这种情况下,浏览器不关心从AJAX请求接收响应),但得到其他开发人员的一些确认将非常感谢

此外,如果<a>链接指向内部网址而不是外部网址,上述问题的答案会有所不同吗?

<script type="text/javascript">
    $(document).ready(function() {
        $('.record-outbound-click').on('click', function(event) {
            var link = $(this);
            $.post(
                '/save-outbound-link-data',
                {
                    destination: link.attr('href'),
                    category:    link.data('cat')
                },
                function() {
                    // Link tracked successfully.
                }
            );
        });
    });
</script>
<a href="http://www.stackoverflow.com" class="record-outbound-click" data-cat="programming">
    Visit Stack Overflow
</a>

请注意,使用event.preventDefault()以及window.location.href = var.attr('href')成功回调中的$.post对我来说不是一个可行的解决方案。也没有将用户发送到我的服务器上的初步脚本(例如,/ outbound?cat = programming&amp; dest = http://www.stackoverflow.com),捕获他们的数据,然后将它们重定向到目的地。

1 个答案:

答案 0 :(得分:2)

编辑2

还要考虑握手步骤(Google's docs):

  

建立连接所需的时间,包括TCP握手/重试和协商SSL。

我不认为您和您发送AJAX请求的服务器可以完成握手,如果您的客户端不再打开以连接到服务器(即,您已经在Stackoverflow或您的链接导航到的任何网站。)

编辑1

  

更广泛地说,我希望从理论的角度来理解我所担心的风险是否合法。

这是一个有趣的问题,答案可能并不像看起来那么明显。

enter image description here

这只是我的网络标签中的示例请求/响应。绝对不应该被认为是用作一般请求/响应的任何趋势或表示。

我认为我们最关心的差距是1.933ms的停滞时间。在发送实际请求之前还需要执行其他其他步骤(其本身大约为0.061毫秒)。

如果在导致实际请求的3个步骤中的任何一个步骤中断(花费大约35毫秒给予或接受),我会担心。

我认为问题是,如果你去了#34; stalled&#34;,&#34; DNS查询&#34;和&#34;初始连接&#34;步骤发生,请求仍然会被发送?那部分,我不知道。但是事先计算机或浏览器的延迟呢?

就像你提到的那样,以某种方式来自Stackoverflow的req / res周期比你客户端上发生的更快(即,启动本身 - 甚至不是整个周期 - 对你的服务器的网络请求)可能有点荒谬,但我认为理论上(正如你所提到的,这是你感兴趣的),一般来说依赖这些类型的可能是一个坏主意。竞争条件。

原始答案

如何使AJAX请求同步?

$.ajax({
    type: "POST",
    url: url,
    async: false
});

这通常是一个糟糕的想法,但是如果在你的情况下,遗留代码是如此限制,你无法修改它,这是你的最后选择(想想,僵尸启示录),那么考虑它。

请参阅jQuery: Performing synchronous AJAX requests

这个坏主意的原因是因为它完全阻止了(在正常情况下,您不希望阻止主线程的潜在不完整请求)。但在你的情况下,看起来它实际上完全你想要的东西。