Chrome 中 JQuery 停止和挂起的 ajax 请求
Posted
技术标签:
【中文标题】Chrome 中 JQuery 停止和挂起的 ajax 请求【英文标题】:Stalled and pending ajax requests by JQuery in Chrome 【发布时间】:2015-03-16 14:30:03 【问题描述】:有时,我的应用程序中的 Ajax 调用(通过 JQuery 1.8)会长时间停留在“待处理”状态(有时长达 17 分钟)。 我用谷歌搜索过,所有可能的解决方案都不起作用:
-
我没有安装广告拦截器。
我在 Chrome 中禁用了“预测网络操作以提高页面加载性能”标志。
我还在 Ajax 调用中添加了一个查询字符串以使其唯一(以禁用任何 Chrome 缓存锁定)。
你知道如何解决这个问题吗?
在下面的示例中,请求等待了 17 分钟(通过 Fiddler 验证它仅在 17 分钟后发送)。
GET http://www.mywebsite.com/foo/rest/publishers/1/packages?_=1421584749323 HTTP/1.1
Host: www.mywebsite.com
Connection: keep-alive
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/39.0.2171.99 Safari/537.36
Content-Type: application/json
Referer: http://www.mywebsite.com/foo/client/home
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,he;q=0.6,ru;q=0.4
Cookie: JSESSIONID=C668509B5AFCDEBE9C9774C4721AFB9D;
aaassz="ddss"
看图:
【问题讨论】:
你有轮询周期吗?我也有这个问题,因为有很多请求(50 1,5 秒)。所以,chrome 一直等到他们完成,然后才(26 秒后)处理最新的请求,即使它只需要 0.1 秒。 我每 5 分钟有一个轮询周期。但是,我们看不出它如何证明 Chrome 停止 17 分钟是合理的。减少轮询间隔是否解决了您的问题? 根据developer.chrome.com/devtools/docs/…说明,停滞时间是请求在发送之前等待的时间。这个时间包括代理协商所花费的任何时间. 此外,此时间将包括浏览器等待已建立的连接可供重新使用的时间,遵守 Chrome 的每个源规则最多六个 TCP 连接。 我在发出请求时收到相同的待处理消息,在我的情况下,我从服务器端接收的数据存在一些问题,我选择了一个新的匿名类型(使用 C# 和 LINQ)而不是整个模型并发送它,它起作用了,但我不知道为什么。 如果您的一项服务未完成请求并发送响应,您最终将导致所有 ajax 请求处于待处理状态。查看第一个为您提供待处理状态的服务。 【参考方案1】:你可以试试这个。
现已更新为实际工作代码
(使用了我自己的一些时区代码,请原谅对时区的引用)
首先初始化数组并运行你的请求计数逻辑
var request = ( typeof request != 'undefined' && request instanceof Array ) ? request : [];
var pendingAjax = ( typeof pendingAjax != 'undefined' && pendingAjax instanceof Array ) ? pendingAjax : [];
使用.ajaxStart 和.ajaxStop 跟踪活动请求。
var ajaxActive = 0;
$( document ).ajaxStart(function()
ajaxActive++;
document.ajaxQueueFull = ajaxActive > 5;
);
$(document).ajaxStop(function()
ajaxActive--;
document.ajaxQueueFull = ajaxActive > 5;
创建一个函数来构建新的请求
function ajaxRequestNew(t, u, d, s)
var instance = request.length + 1;
request[instance] = $.ajax(
method: t,
url: u,
data: ajaxPost: d ,
success: s
);
return instance;
现在创建您的请求以获取返回的实例编号
var instance = ajaxRequestNew('POST',
'js/ajax_timezone.php',
ajaxAction : "ajaxGetTimezone",
tzoffset : "0",
tztimezone: "America/New_York" ,
function(data)
);
$.ajax() 函数返回一个 XMLHttpRequest 对象。因此,我们使用 while 循环来检查我们的 ajax 何时真正被发送,并在请求停止时中止其他活动请求。
while(request[instance] === null || (request[instance].readyState < 1 || request[instance].readyState > 4))
if (document.ajaxQueueFull)
//abort existing requests
$.each(request, function(i,v)
if (i !== instance)
request[i].abort();
);
将您的请求推入堆栈
pendingAjax.push(request[instance]);
为您的请求创建回调
var timezoneFailCallback = function(data)
console.log('fail');
console.dir(data);
;
var timezoneSuccessCallback = function(data)
console.log('success');
console.dir(data);
;
使用何时应用回调
$.when.apply($, pendingAjax).done( timezoneSuccessCallback ).fail( timezoneFailCallback);
代码可能需要对您的应用进行一些调整,但希望您能理解。如果您有任何问题,请告诉我。
【讨论】:
如果特定端点上的请求停止,这将解决问题,但如果所有请求都停止,而不管端点如何?在我的情况下,Chrome 在进入此状态时仅每秒启动一次请求(也许 Chrome 正在限制请求,因为应用程序一次发送太多,有点限制 Chrome 认为是行为不良的应用程序)? 【参考方案2】:我偶然发现了完全相同的问题。一旦我禁用:
使用预测服务更快地加载页面
转到 高级设置 -> 隐私 -> ca。第三个复选框,一切都开始正常工作。我无法重现该错误。
jquery/ajax
轮询器在 Firefox 中完美运行。它只是 Chrome - 在 Linux 和 Windows 上测试。
这不是一个完美的解决方案,因为它不会影响全球范围内的用户 - 但也许你和我的情况相同 - 受众有限。
【讨论】:
这似乎也解决了我的问题。 这对我的情况没有任何影响,但有趣的假设。简单地说,Chrome 将每个选项卡/会话的未完成请求数限制为 6 个,因此可能在后台发生的其他事情没有显示在 Chrome 的开发工具中的网络监视器中。【参考方案3】:我知道这是一个旧线程,但我将其发布给那些争先恐后地为此寻找某种答案的人。 我也不得不处理这个令人头疼的问题。我的问题是由于广告拦截器阻止了其中包含“优惠券”一词的 API 调用。它在保持请求状态的同时阻止了请求。在几个块之后,每个请求都会自动进入挂起状态,因为有太多(我认为大约 6 或 7 个)实时请求。
在您的 chrome 地址栏中键入 chrome://net-internals/#events 以检查请求。这将使您更清楚地了解问题。 我附上了两张我在试图弄清楚这一点时拍摄的图像。
debugger screenshot
net-internal screenshot
【讨论】:
【参考方案4】:如果您控制服务器端,这可能适用于您的情况: 添加到服务器的响应 headers[ 'Connection' ] = 'close' 就我而言,“保持活力”是问题的原因
【讨论】:
【参考方案5】:经过三天的头疼,我意识到我在 mysql 事务中调用了一个数据库备份函数。
【讨论】:
以上是关于Chrome 中 JQuery 停止和挂起的 ajax 请求的主要内容,如果未能解决你的问题,请参考以下文章
当应用程序被终止时并在后台使用 FusedLocationProviderClient 和挂起的 Intent 但在不规则时间获取位置