Firefox在以前的尝试失败时未完成一系列调用

时间:2013-02-27 03:59:30

标签: javascript jquery firefox

我有一个脚本,用GET方法ping一系列网址。我只希望每次ping一次,不要期待响应。我的脚本适用于Chrome和Safari,但Firefox无法完成后续请求。

有没有办法触发Firefox一次性进行一系列调用(准确地说是五次),而不关心它们是否失败?当第一个请求失败时,Firefox似乎无法完成一系列请求。

我正在javascript和jQuery中工作,引入了一点jQuery.ajax()。我搜索过,无济于事,已达到初学者技能组的极限。任何见解都将不胜感激。

(如果您对整个范围感兴趣,可以在jquery-based standalone port knocker

处找到代码

谢谢。


更新

经过进一步研究,我认为问题是Firefox并没有真正异步处理这些调用。我有使用img调用的ping代码版本,iframe url调用,以及在Chrome和Safari中使用的ajax调用,但在Firefox中,它们的行为并不像我需要的那样。

我们对爆震序列的服务器监控应该看到请求顺序到端口1,2,3,4,5(就像使用Chrome或Safari时那样)但是在Firefox中,无论我尝试了哪种方法,我看到第一次尝试ping端口1两次,然后是端口2,并且在后续尝试中我只看到ping端口1.我的状态更新按预期显示,但服务器没有按照它需要的顺序接收呼叫。似乎Firefox正在重试失败的调用而不是按顺序执行每一次调用,这就是我需要它做的事情。

以下是使用简单jquery.ajax调用方法的脚本示例。它适用于Safari和Chrome,但在Firefox中无法达到预期的效果。当我的所有代码都运行并且我可以看到状态更新(使用jquery.append函数生成)时,请求不会每次发送一次,顺序发送到我的服务器。

<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('button').click(function(){
    $('#knocks').append('<p>Knocking...</p>');
    setTimeout(function(){
        $.ajax({url: 'https://example.sample.com:1111'});
        $('#knocks').append("<p>Knock 1 of 5 complete...</p>");
        }, 500);    
    setTimeout(function(){
        $.ajax({url: 'https://example.sample.com:2222'});
        $('#knocks').append("<p>Knock 2 of 5 complete...</p>");
        }, 3500);
    setTimeout(function(){
        $.ajax({url: 'https://example.sample.com:3333'});
        $('#knocks').append("<p>Knock 3 of 5 complete...</p>");
        }, 6500);
    setTimeout(function(){
        $.ajax({url: 'https://example.sample.com:4444'});
        $('#knocks').append("<p>Knock 4 of 5 complete...</p>");
        }, 9500)
    setTimeout(function(){
        $.ajax({url: 'https://example.sample.com:5555'});
        $('#knocks').append("<p>Knock 5 of 5 complete...</p>");
        }, 12000);
    setTimeout(function(){
        $('#knocks').append("<p>Knocking is complete... <br>Proceed to site: <a href='http://example-url.sample-url.com'>http://example-url.sample-url.com</a></p>");
        }, 13000);
});
});
</script>

1 个答案:

答案 0 :(得分:0)

看到你的问题没有真正的答案,你可能想继续前进,我虽然我会给你一些建议作为起点。

为了让您的函数调用真正按顺序执行(或同步按顺序阻止,...)您必须确保在进行的请求完成后(成功或失败)发出所有后续函数调用(在您的情况下为AJAX请求),在这种情况下,您可能不希望继续下一个有序调用并发出完全独立的回应)。

现在你的方式不被认为是同步,而是实际上是异步,延迟(或者在后台“超时”)。当您希望AJAX调用在服务器端同步执行(阻塞)时,这可能会导致各种问题。从浏览器重新发出失败或超时请求(由于各种原因,取决于它们的功能集以及它们如何处理失败的请求,缓存......),以便在启用某些预取程序时抢先发出请求和缓存结果(或但是他们在FF中调用它,然后如果预取器失败则再次重新发出它们。我相信这与您在Firefox中观察到的类似,可能是这种意外行为的罪魁祸首。由于您无法控制最终用户在其浏览器中启用或禁用的功能,或者他们在未来版本中实现了哪些新功能,因此您不能期望通过使用setTimeout延迟其呼叫来执行异步执行服务器调用,即使他们似乎在其他浏览器中这样做(可能是因为您的服务器响应速度足够快,因此它们会出现)。

在你的代码中,第二个调用似乎只是执行同步(等待第一个完成)最多半秒,第三个请求最多3秒和一个一半,等等。但即使setTimeout阻止执行(它没有),它会等待哪个外部请求?第一个,还是第二个?我认为你得到的是我想说的以及为什么你的代码没有按预期工作。

相反,您应该通过服务器的响应发出后续的AJAX调用(这实际上是使用AJAX的点,否则不需要它),或者最好是创建一个外部侦听器函数来处理这些调用。您之前外部呼叫的状态和/或返回值。如果您还需要处理失败的请求并继续执行,那么外部侦听器(具有预设的执行堆栈超​​时)是可行的方法,因为您显然无法依赖失败请求的响应。

您看,浏览器在发出多个并发请求时没有问题,并且使用setTimout延迟它们并不会阻止预取程序尝试缓存其响应以供以后使用。它也不会以阻塞方式发出请求,下一个请求等待前一个请求完成,正如您所期望的那样。大多数人都乐于利用一定数量的并发连接(客户端机器上大约10个,服务器上大多数),以加快下载和/或页面呈现过程,有些甚至更高级出于同样的原因,缓存机制到位,Firefox只是其中之一。

我希望这可以解决一些问题,并且您将能够重写代码以按预期工作。由于我们不知道您的服务器端代码应该如何工作,所以您必须自己编写代码。然而,SE上有很多线程讨论您可能决定使用的类似技术,如果您遇到困难,您可以随时提出另一个问题,我们很乐意提供帮助。

干杯!