我有一个长时间运行的服务调用,我使用jQuery.ajax调用。该服务可能需要2分钟才能完成。
提交了AJAX请求,预计不会响应。一个单独的AJAX请求报告操作的进度。
在某些网站上,我们发现代理在2分钟后重新提交Ajax请求本身。浏览器是Chrome浏览器,但我怀疑它与Chrome有关。
这绝对不是我们重新提交ajax请求的情况。为了确保我们设置bool以防止在beforeSend事件中重新提交任何内容。
我正在处理这种重新提交的方式是在数据请求和服务测试中添加一个nonce,如果在执行操作之前已经提交了nonce。对此服务的任何第二次调用都会无害地返回,并且原始请求将继续进行。
请注意,我添加了一个毫无意义的服务,除了等待5分钟之外什么都没做,而且我没有遇到过测试服务的问题(在生产网站上)。
任何人都可以向我提供有关导致此ajax重新提交的原因的任何线索,以及如何在本地复制它?
这是用于发送请求的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://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;
}
});
这是从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"
答案 0 :(得分:2)
同样的故事。如果到目前为止客户端没有收到响应,jQuery显然会在120秒(默认超时)后重新发送请求。
增加超时时间,如下所示:
$.ajax({
url: localhost,
type: 'POST',
timeout: 1000*60*10
不会改变游戏。请求在2分钟后仍然重新发送,尽管客户端仍在等待任何响应。
虽然服务器端能够很好地并行处理这两个请求,但是客户端请求对第一个请求的有效响应有效。
还没有解决方案
编辑:
事实证明,浏览器就是那个重新发送事件并且该行为完全符合HTTP / 1.1规范的浏览器。并且实际上(node.js)后端在超时120秒后关闭了套接字,例如jonasnas指向的。解决方案是在响应对象上禁用超时,如: // this is a long running request,
// so disable response timeout
response.setTimeout(0);
答案 1 :(得分:0)
如果请求始终在2分钟内处理,则表明您的服务器端(node.js)未正确完成响应(使用rsp.end()
)。 2分钟是express/node
服务器上的默认超时。
答案 2 :(得分:0)
不幸的是,这里的所有其他(浏览器端)建议对我而言都行不通。但是,只需让ajax请求超时立即完成工作即可:
这可以通过以下方式实现:
$.ajax("https://someurl/", {
...
timeout:1
...
});
作为旁注:将超时设置为0无效。
如果服务器端计算花费的时间太长,那么无论如何都在这里等待是没有意义的。需要单独的解决方案来检查计算是否完成。
这种方法看起来很糟糕。因此,仍然欢迎任何更好的工作解决方案;-)
答案 3 :(得分:0)
移动评论以获取更多可见性。 我们的问题是负载平衡器。当我们通过LB URL从AJAX调用Web api服务时,我们收到了120秒的问题,并且对该服务进行了重复调用,而客户端没有代表性的额外调用。 当我们通过直接服务器节点调用api并从等式中删除负载均衡器时,我们不会遇到问题。 如果您的负载均衡器在您的方程式中,请调查直接调用服务器节点是否有效。如果是这样,请寻求负载均衡器支持。
作为一种临时解决方法,在解决LB问题之前,我将在页面加载时将服务器节点名称返回到客户端页面的隐藏字段中,并让我的JS代码使用它来构造用于调用服务的直接URL。