【问题标题】:Not Receiving Asynchronous AJAX Requests When Sent Rapidly快速发送时不接收异步 AJAX 请求
【发布时间】:2012-12-31 12:05:27
【问题描述】:

我的脚本正在向一个页面 (http://example.org/getlisting/) 发送一个 GET 请求,而该页面又用一个 JSON 对象进行响应。 ({"success":true, "listingid":"123456"})

这是一个示例 sn-p:

var listingAjax = new XMLHttpRequest();
listingAjax.addEventListener("load", listingCallback, false);

function listingCallback(event) {
    if (this.readyState == 4 && this.status == 200) {
       console.log(this.responseText);
    }
}

listingAjax.open("GET", "http://example.org/getlisting/", true);
listingAjax.send();

足够简单。该脚本也可以完美运行!当我想这样做时会出现问题:

var listingAjax = new XMLHttpRequest();
listingAjax.addEventListener("load", listingCallback, false);

function listingCallback(event) {
    if (this.readyState == 4 && this.status == 200) {
       console.log(this.responseText);
    }
}

window.setInterval(function() {
    listingAjax.open("GET", "http://example.org/getlisting/", true);
    listingAjax.send();
}, 250);

我想应该发生的是我的脚本将创建一个稳定的 GET 请求流,这些请求被发送到服务器,然后服务器响应每个请求。然后,我的脚本将接收服务器的响应并将它们发送到回调。

更准确地说,假设我让这个脚本运行了 5 秒,我的脚本在那段时间内向服务器发送了 20 个 GET 请求。我希望我的回调 (listingCallback) 也会被调用 20 次。

问题是,事实并非如此。似乎,如果我在收到来自服务器的响应之前发送了两个 GET 请求,那么响应就会被忽略或丢弃。

我做错了什么/对此有误解?

【问题讨论】:

  • 您在哪些浏览器中看到了这种行为?我不确定为什么会这样,但我想知道它是否是特定于浏览器的。
  • 这是谷歌浏览器。因为我计划将来将此脚本转换为 NodeJS 应用程序(明年某个时间;)),所以我计划使其具体化

标签: javascript ajax asynchronous xmlhttprequest


【解决方案1】:

许多浏览器都内置了每个服务器的最大打开 HTTP 连接数。你可能会撞到那面墙?

这是来自 Mozilla 的示例,但大多数浏览器都应该内置这样的内容:http://kb.mozillazine.org/Network.http.max-connections-per-server

关于 Chrome 的较早问题: Increasing Google Chrome's max-connections-per-server limit to more than 6

如果您有 Windows,请查看 Fiddler 之类的工具 - 您可能能够查看是否所有请求都实际发出,或者浏览器是否正在排队/杀死其中一些请求。

【讨论】:

  • 是的。这个。 @NessDan,每四分之一秒的 GET 请求很多(太多)。如果您需要实时信息,请考虑使用其他使用持久连接的解决方案,例如长轮询或 Web 套接字。
  • 谢谢你,幸好不是这样(我不知道 GET 请求是否也算作连接。)
【解决方案2】:

您不能在新连接正在进行时重复使用相同的XMLHttpRequest 对象opening,否则会导致突然的abortion(在 Chrome 中测试)。为每个调用使用一个新的 XMLHttpRequest 对象将解决这个问题:

function listingCallback(event) {
    if (this.readyState == 4 && this.status == 200) {
       console.log(this.responseText);
    }
}

window.setInterval(function() {
    var listingAjax = new XMLHttpRequest();
    listingAjax.addEventListener("load", listingCallback, false);
    listingAjax.open("GET", "http://example.org/getlisting/", true);
    listingAjax.send();
}, 250);

这将很好地为每个间隔排队一个新的 ajax 请求。

Fiddle

请注意,由于每个浏览器固有的并发 ajax 调用的最大限制,过于频繁的调用可能会导致速度变慢。
不过,现代浏览器有一个相当公平的限制和非常好的并行性,所以只要您只获取一个小的 JSON 对象,现代浏览器即使在使用拨号时也应该能够跟上。

上次我制作 ajax 轮询脚本时,我会在前一个请求的成功处理程序中启动一个新请求,而不是使用间隔,以最大限度地减少 ajax 调用。但不确定此逻辑是否适用于您的应用。

【讨论】:

  • 成功了!有效!有效!你不知道我已经把这件事搞砸了多久!非常感谢您的回答,我很感激! “我有没有告诉过你,你是我的英雄?” :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-26
  • 1970-01-01
  • 2013-12-05
  • 2011-05-26
  • 2021-10-12
  • 2015-06-25
  • 1970-01-01
相关资源
最近更新 更多