0

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

这是一个示例片段:

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 请求,那么响应就会被忽略或丢弃。

我在做什么错/误解?

4

2 回答 2

2

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

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

关于 Chrome 的较早问题:将 Google Chrome 的 max-connections-per-server 限制增加到 6 以上

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

于 2012-12-31T03:43:39.607 回答
1

您不能在新连接正在进行时重用相同的XMLHttpRequest对象open,否则会导致突然的abort离子(在 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 请求。

小提琴

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

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

于 2012-12-31T03:54:26.967 回答