Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with browser's limit of parallel requests per domain in case of a priority AJAX request?

Imagine as given the following situation:

There are about 20 requests (or even more) which has been triggered by our website. These can be any kind of requests - we don't know how to trigger them again. On this website, all the requests target the same url. The requests can have subscribed event listeners.

In case of using Chrome, the first 6 requests are sent and the others are waiting in a queue to be sent (because of the parallel request limit per domain).

At this moment the webpage triggers a very important request (lets call it "VIR") which has a higher priority to be sent to the server then the previous 20 requests. The other requests (and their event listeners) are also kind of important so we can't just abort them to send the VIR immediately.

We need a solution to get all the pending requests (6 sent + 14 in the queue), abort them, then send the VIR, and then send the others again with the same event listeners attached that they had before.

In case of no other (out of the box) solution, the 2 basic questions are:

  • Is it possible to get reference to all the pending requests (including the queue)?
  • Is it possible to abort an xhr and then send it again (by cloning them somehow, or I don't know)?

And another related question:

  • I remember that the parallel requests limit per Hostname is a limit for the browser and not for the current tab only. Is there a magical solution to handle it? If yes, do I really want to write that? :)

Be aware of that all the requests have to be sent the same domain. (Means that targeting a different domain with the VIR is not an option here). However using websocket or http/2 could solve the basic problem, those are not options in this current question.

I appreciate any idea on this! Thx in advance!

pm.: And yes, it's a javascript question :)

like image 612
Burnee Avatar asked Aug 22 '16 18:08

Burnee


1 Answers

You can actually keep using the same XmlHttpRequest instance after aborting the request, calling the open and send methods again, and the event listeners remain attached. Updated the snippet with overloading the xhr open/send method to save the url and payload:

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);
  })
}
like image 153
yscik Avatar answered Sep 28 '22 22:09

yscik