长时间运行的AJAX请求会在几分钟后重新提交

时间:2022-11-15 01:18:05

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

我有一个长时间运行的服务调用,我使用jQuery.ajax调用。该服务可能需要2分钟才能完成。

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

提交了AJAX请求,预计不会响应。单独的AJAX请求报告操作的进度。

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.

在某些网站上,我们发现代理在2分钟后重新提交Ajax请求本身。浏览器是Chrome,但我怀疑它与Chrome有关。

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.

这肯定不是我们重新提交ajax请求的情况。为了确保我们设置bool以防止在beforeSend事件中重新提交任何内容。

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.

我现在处理这种重新提交的方式是在数据请求和服务测试中添加一个nonce,如果在执行操作之前已经提交了nonce。对此服务的任何第二次调用都会无害地返回,并且原始请求将继续进行。

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).

请注意,我添加了一个无意义的服务,除了等待5分钟之外什么也没做,而且我没有遇到测试服务的问题(在生产站点上)。

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

任何人都可以给我任何线索,导致这个ajax重新提交的原因,以及如何在本地复制它?

This is the js used to send the request:

这是用于发送请求的js:

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://*.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.

这是从HTTP存档(HAR)请求的ajax,其中请求被重新提交并且它立即失败。注意2分钟的时间。

{
"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"

2 个解决方案

#1


1  

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.

同样的故事在这里如果到目前为止客户端没有收到任何响应,jQuery显然会在120秒(默认超时)后重新发送请求。

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.

不改变游戏。尽管客户端仍在等待任何响应,但请求仍会在2分钟后重新发送。

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:

事实证明,浏览器就是那个重新发送事件并且该行为完全符合HTTP / 1.1规范的浏览器。并且实际上(node.js)后端在超时120秒后关闭套接字,例如jonasnas指向的。解决方案是在响应对象上禁用超时,如下所示:

    // this is a long running request,
    // so disable response timeout
    response.setTimeout(0);

#2


0  

If request is handled always in 2min its an indication that your server side (node.js) is not finishing the response properly (with rsp.end()). 2 minutes is the default timeout on the express/node server.

如果请求总是在2分钟内处理,则表明您的服务器端(node.js)未正确完成响应(使用rsp.end())。 2分钟是快速/节点服务器上的默认超时。

#1


1  

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.

同样的故事在这里如果到目前为止客户端没有收到任何响应,jQuery显然会在120秒(默认超时)后重新发送请求。

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.

不改变游戏。尽管客户端仍在等待任何响应,但请求仍会在2分钟后重新发送。

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:

事实证明,浏览器就是那个重新发送事件并且该行为完全符合HTTP / 1.1规范的浏览器。并且实际上(node.js)后端在超时120秒后关闭套接字,例如jonasnas指向的。解决方案是在响应对象上禁用超时,如下所示:

    // this is a long running request,
    // so disable response timeout
    response.setTimeout(0);

#2


0  

If request is handled always in 2min its an indication that your server side (node.js) is not finishing the response properly (with rsp.end()). 2 minutes is the default timeout on the express/node server.

如果请求总是在2分钟内处理,则表明您的服务器端(node.js)未正确完成响应(使用rsp.end())。 2分钟是快速/节点服务器上的默认超时。