【问题标题】:Stalled and pending ajax requests by JQuery in ChromeChrome 中 JQuery 停止和挂起的 ajax 请求
【发布时间】:2015-03-16 14:30:03
【问题描述】:

有时,我的应用程序中的 Ajax 调用(通过 JQuery 1.8)会长时间停留在“待处理”状态(有时长达 17 分钟)。 我用谷歌搜索过,所有可能的解决方案都不起作用:

  1. 我没有安装广告拦截器。
  2. 我在 Chrome 中禁用了“预测网络操作以提高页面加载性能”标志。
  3. 我还在 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 请求处于待处理状态。查看第一个为您提供待处理状态的服务。

标签: jquery ajax google-chrome xmlhttprequest


【解决方案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 事务中调用了一个数据库备份函数。

      【讨论】:

        猜你喜欢
        • 2019-05-21
        • 1970-01-01
        • 2012-02-02
        • 1970-01-01
        • 2014-01-30
        • 1970-01-01
        • 2018-03-22
        • 1970-01-01
        • 2010-12-20
        相关资源
        最近更新 更多