2016-08-22 110 views
3

想象一下,给定以下情况:如何处理AJAX请求优先级的情况下浏览器对每个域的并行请求限制?

有大约20个请求(甚至更多),这是由我们的网站触发的。这些可以是任何类型的请求 - 我们不知道如何再次触发它们。在这个网站上,所有请求的目标地址都是相同的。请求可以有订阅事件侦听器。

在使用Chrome的情况下,前6个请求被发送,其他人在队列中等待发送(因为parallel request limit per domain)。

此时网页触发了一个非常重要的请求(让我们称之为“VIR”),它具有更高的优先级,然后发送到服务器,然后是前20个请求。其他请求(以及它们的事件监听器)也非常重要,所以我们不能立即中止它们发送VIR。

我们需要一个解决方案,使所有未决请求(6队列发送+ 14),中止它们,然后发送VIR,然后用连接,他们收到了相同的事件监听器再次发送其他

在任何其他情况下(开箱即用)解决方案,在2个基本问题是:

  • 是否有可能得到引用的所有未决请求(包括队列)?
  • 是否有可能放弃一个xhr然后再发送它(通过克隆它们,或者我不知道)?

而另一个相关的问题:

  • 我记得每个主机名的并行请求限制是浏览器,而不是只为当前选项卡的限制。是否有一个神奇的解决方案来处理它?如果是的话,我真的想写吗? :)

注意的,所有的请求都必须发送同一个域。 (意味着在VIR中定位不同的域名不是一种选择)。 但是使用websocket或http/2可以解决基本问题,但这些不是当前问题中的选项。

我很欣赏这个! Thx提前!

点:是的,这是一个JavaScript的问题:)

+6

您的实际问题是针对同一个URL 20个并发Ajax请求。修复。 – Bergi

+1

您可以重写'XMLHttpRequest.prototype.send',以在发送请求时向列表中添加请求,并且在该覆盖函数中还添加完成侦听器以将其从列表中删除,类似于http:// stackoverflow。COM/A/18259603 /。但一旦你完成了,重新发送请求就无法完成;你需要建立一个新的。为了达到这个目的,你必须捕获关于请求的所有信息,这也意味着覆盖'open','setRequestHeader'等等(我认为Bergi真的有正确的想法,不过'')') – apsillers

+0

是的,Bergi可能是对的,但这个问题本身就是为了看看你如何处理这种情况。我期待你给出的答案。虽然我在询问有关克隆xhr对象的更多细节。我应该用旧的属性覆盖新xhr的所有属性吗?或者我应该排除一些?这是否也“复制”了xhr的事件处理程序? – Burnee

回答

3

实际上,你可以继续使用相同的XmlHttpRequest实例中止请求后,调用open并再次发送方法,以及事件侦听器保持连接。更新的代码片段,其中超载XHR开/发送方法来保存URL和有效载荷:

var pending_requests = [], 
 
    XHRBase = { 
 
     open: XMLHttpRequest.prototype.open, 
 
     send: XMLHttpRequest.prototype.send 
 
    }; 
 

 
XMLHttpRequest.prototype.open = function() { 
 

 
    pending_requests.push(xhr._data = {xhr: this, open: arguments}); 
 
    XHRBase.open.apply(this, arguments); 
 
    // add event listener to pop on finish 
 
} 
 

 
XMLHttpRequest.prototype.send = function() { 
 
    xhr._data.send = arguments; 
 
    XHRBase.send.apply(this, arguments); 
 
} 
 

 
function priority_call(params, callback) { 
 
    pending_requests.forEach((req) => req.xhr.abort()); 
 
    // do vip xhr 
 
    pending_requests.forEach((req) => { 
 
    XHRBase.open.apply(req.xhr, req.open); 
 
    XHRBase.send.apply(req.xhr, req.send); 
 
    }) 
 
}

+0

如果我们可以控制所有的请求,这可能是一个很好的解决方案。但是,情况是我们无法控制它们。重写XmlHttpRequest可能是收集所有AJAX调用的解决方案。 – Burnee

+1

原来您可以重新使用xhr实例,并使用该解决方案更新了答案。 – yscik

+0

Big UP哥们! Thx为你的努力,现在它非常接近我所想象的东西。我将在接下来的一周内对此进行研究,从A到Z进行测试。我会回来分享经验。根据结果​​我会接受答案。 – Burnee