2

我有一个使用 GET 方法 ping 一系列 url 的脚本。我只想对它们每次 ping 一次并且不期望得到响应。我的脚本适用于 Chrome 和 Safari,但 Firefox 不会完成后面的请求。

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

我正在使用 javascript 和 jQuery,并添加了一些 jQuery.ajax()。我进行了搜索,但无济于事,并且已经达到了我初学者技能的极限。任何见解将不胜感激。

(如果您对完整范围感兴趣,请参阅基于 jquery 的独立端口敲击器的代码)

谢谢你。


更新:

经过进一步研究,我认为问题在于 Firefox 并没有真正异步处理调用。我的代码版本通过 img 调用、iframe url 调用和 ajax 调用在 Chrome 和 Safari 中工作,但在 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>
4

1 回答 1

0

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

为了使您的函数调用真正按顺序(或同步中序阻塞等)执行,您必须确保在处理请求完成后发出所有后续函数调用(在您的情况下为 AJAX 请求) (成功或失败,在这种情况下,您可能不想继续下一个按顺序调用并发出完全单独的响应)。

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

在您的代码中,第二个调用似乎只同步执行(等待第一个完成)长达半秒,第三个请求长达 3 秒半,依此类推。但即使setTimeout是阻塞执行(它没有),它会等待哪个外部请求?第一个,还是第二个?我想你明白我想说什么以及为什么你的代码不能按预期工作。

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

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

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

干杯!

于 2013-02-27T21:30:02.300 回答