在优先级 AJAX 请求的情况下,如何处理浏览器对每个域的并行请求的限制?
How to deal with browser's limit of parallel requests per domain in case of a priority AJAX request?
想象一下以下情况:
大约有 20 个请求(或更多)是由我们的网站触发的。这些可以是任何类型的请求——我们不知道如何再次触发它们。在这个网站上,所有的请求都指向同一个url。请求可以订阅事件侦听器。
在使用 Chrome 的情况下,前 6 个请求已发送,其他请求在队列中等待发送(因为 parallel request limit per domain)。
此时网页触发了一个非常重要的请求(暂且称它为"VIR"),它比之前的20个请求有更高的优先级发送到服务器。其他请求(及其事件侦听器)也很重要,因此我们不能中止它们以立即发送 VIR。
我们需要一个解决方案来获取所有待处理的请求(发送的 6 个 + 队列中的 14 个),中止它们,然后发送 VIR,然后再次发送其他的他们之前附加的相同事件侦听器。
如果没有其他(现成的)解决方案,2 个基本问题是:
- 是否可以获取所有待处理请求(包括队列)的引用?
- 是否可以中止一个 xhr 然后再次发送它(通过某种方式克隆它们,或者我不知道)?
另一个相关问题:
- 我记得每个主机名的并行请求限制是浏览器的限制,而不仅仅是当前选项卡的限制。有没有神奇的解决方案来处理它?如果是,我真的要写那个吗? :)
注意所有请求都必须发送到相同的域。 (意味着使用 VIR 定位不同的域在这里不是一个选项)。
但是使用 websocket 或 http/2 可以解决基本问题,这些不是当前问题的选项。
我很感激任何关于此的想法!
提前致谢!
pm.: 是的,这是一个 javascript 问题 :)
您实际上可以在中止请求后继续使用相同的 XmlHttpRequest
实例,再次调用打开和发送方法,并且事件侦听器保持附加状态。通过重载 xhr open/send 方法更新代码段以保存 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);
})
}
想象一下以下情况:
大约有 20 个请求(或更多)是由我们的网站触发的。这些可以是任何类型的请求——我们不知道如何再次触发它们。在这个网站上,所有的请求都指向同一个url。请求可以订阅事件侦听器。
在使用 Chrome 的情况下,前 6 个请求已发送,其他请求在队列中等待发送(因为 parallel request limit per domain)。
此时网页触发了一个非常重要的请求(暂且称它为"VIR"),它比之前的20个请求有更高的优先级发送到服务器。其他请求(及其事件侦听器)也很重要,因此我们不能中止它们以立即发送 VIR。
我们需要一个解决方案来获取所有待处理的请求(发送的 6 个 + 队列中的 14 个),中止它们,然后发送 VIR,然后再次发送其他的他们之前附加的相同事件侦听器。
如果没有其他(现成的)解决方案,2 个基本问题是:
- 是否可以获取所有待处理请求(包括队列)的引用?
- 是否可以中止一个 xhr 然后再次发送它(通过某种方式克隆它们,或者我不知道)?
另一个相关问题:
- 我记得每个主机名的并行请求限制是浏览器的限制,而不仅仅是当前选项卡的限制。有没有神奇的解决方案来处理它?如果是,我真的要写那个吗? :)
注意所有请求都必须发送到相同的域。 (意味着使用 VIR 定位不同的域在这里不是一个选项)。 但是使用 websocket 或 http/2 可以解决基本问题,这些不是当前问题的选项。
我很感激任何关于此的想法! 提前致谢!
pm.: 是的,这是一个 javascript 问题 :)
您实际上可以在中止请求后继续使用相同的 XmlHttpRequest
实例,再次调用打开和发送方法,并且事件侦听器保持附加状态。通过重载 xhr open/send 方法更新代码段以保存 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);
})
}