Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Long running AJAX request resubmits after a couple of minutes

I have a long running service call, that I call using jQuery.ajax. The service can take well over 2 minutes to complete.

The AJAX request is submitted, and no response is expected. A separate AJAX request reports on the progress of the operation.

On some sites, we have found is that after 2 minutes the agent resubmits the Ajax request itself. The browser is Chrome, but I doubt its a Chrome related issue.

This definitely is not a case of us resubmitting the ajax request. To be sure we set a bool to prevent any re-submission in the beforeSend event.

The way I am handling now handling this re-submission, is by adding a nonce to the data request and the service tests if the nonce has already been submitted prior to carrying out its operation. Any second call to this service harmlessly returns and the original request continues to progress.

Note that I added a pointless service that does nothing but waiting for 5 minutes, and not once have I experienced the problem with the test service (on the production sites).

Can anyone give me any clues to what is causing this ajax re-submission, and how to go about reproducing it locally?

This is the js used to send the request:

var sent = false;
var data = { ... }; // data is a very large object;

$.ajax("service.ashx?loc=area/subarea/", {
    type: "POST",
    data: data,
    traditional: true,
    error: function (jqXHR, textStatus, errorThrown) {
        if (jqXHR.status === 0) {
            // see http://stackoverflow.com/questions/3825581/does-an-http-status-code-of-0-have-any-meaning

        } else {
            ReportFailure(textStatus,errorThrown);
        }
    },
    beforeSend: function () {
        if (sent === true) {
            return false;
        }
        sent = true;
        return true;
    }
});

Here is the ajax requested from a HTTP archive (HAR) where the request was re-submitted and it instantly failed. Notice the 2 minute time.

{
"startedDateTime": "2015-12-11T12:26:58.018Z",
"time": 120066.61499999973,
"request": {
  "method": "POST",
  "url": "https://example.com/service.ashx?loc=area/subarea/",
  "httpVersion": "HTTP/1.1",
  "headers": [
    ... // removed for brevity
  ],
  "queryString": [
    { "name": "loc", "value": "area/subarea/" }
  ],
  "cookies": [
    ... // removed for brevity
  ],
  "headersSize": 1163,
  "bodySize": 48048,
  "postData": {
    "mimeType": "application/x-www-form-urlencoded; charset=UTF-8",
    "text": ..., // removed for brevity
    "params": [
      ... // removed for brevity        ] }
},
"response": {
  "status": 500,
  "statusText": "Internal Server Error",
  "httpVersion": "HTTP/1.1",
  "headers": [
    {
      "name": "Date",
      "value": "Fri, 11 Dec 2015 12:28:57 GMT"
    },
    ... // removed for brevity
  ],
  "cookies": [],
  "content": {
  "size": 54,
  "mimeType": "text/xml",
  "compression": 0
  },
  "redirectURL": "",
  "headersSize": 305,
  "bodySize": 54,
  "_transferSize": 359
},
"cache": {},
"timings": {
  "blocked": 120005.055999998,
  "dns": -1,
  "connect": -1,
  "send": 1.0939999989932403,
  "wait": 59.986000001008506,
  "receive": 0.47900000172376167,
  "ssl": -1
},
"connection": "7498"
like image 711
Drew Williams Avatar asked Dec 14 '15 11:12

Drew Williams


People also ask

How do I send an Ajax request after some time?

Use setInterval() when you want to send AJAX request at a particular interval every time and don't want to depend on the previous request is completed or not. But if you want to execute the AJAX when the previous one is completed then use the setTimeout() function.

How do I stop multiple Ajax calls from repeated clicks?

}); If isLoading is false, the AJAX call starts, and we immediately change its value to true. Once the AJAX response is received, we turn the value of that variable back to false, so that we can stop ignoring new clicks.

How can I improve my Ajax performance?

Reducing the number of requests performed, and the amount of data included in both sides of the transaction, will have a dramatic impact on your Ajax performance. Making server changes will help, too, but may be beyond your control.

What is default Ajax timeout?

JIRA has a default AJAX timeout period so that requests in the browser do not run for unlimited amounts of time. Normally 30 seconds is plenty of time for a typical data request. AJAX timeouts can be caused by many different things.


1 Answers

Same story here. jQuery obviously resends a request after 120 seconds (the default timeout) if no response has been received by the client so far.

Increasing the timeout as in:

    $.ajax({
      url: localhost,
      type: 'POST',
      timeout: 1000*60*10

doesn't change the game. Request still resends after 2 minutes, although the client continues to wait for any response.

although the server side is able to handle these two requests in parallel nicely, the clients request failes on valid response of the first request.

no solution yet

EDIT:

it actualy turned out, that the browser is the one, that resends the event and that behavior is fully compliant with HTTP/1.1 specs. And actualy the (node.js) backend closed the socket after a timeout of 120 seconds, such as jonasnas pointed to. The solution was to disable timeout at the response object, as in:

    // this is a long running request,
    // so disable response timeout
    response.setTimeout(0);
like image 178
chhtm Avatar answered Oct 07 '22 21:10

chhtm