簡體   English   中英

Chrome無法處理jquery ajax查詢

[英]Chrome not handling jquery ajax query

我在jquery中有以下查詢。 它正在讀取使用Nginx的長輪詢模塊設置的Nginx訂閱/發布對的“發布”地址。

function requestNextBroadcast() {
        // never stops - every reply triggers next. 
        // and silent errors restart via long timeout. 
        getxhr = $.ajax({
            url: "/activity",
            // dataType: 'json',
            data: "id="+channel,
            timeout: 46000, // must be longer than max heartbeat to only trigger after silent error. 
            error: function(jqXHR, textStatus, errorThrown) {
                alert("Background failed "+textStatus);  // should never happen 
                getxhr.abort(); 
                requestNextBroadcast();  // try again
            },
            success: function(reply, textStatus, jqXHR) {
                handleRequest(reply);   // this is the normal result. 
                requestNextBroadcast(); 
            }
        });
    }

該代碼是聊天室的一部分。 發送的每條消息都以null rply(200 / OK)回復回復,但數據已發布。 這是在數據返回時讀取訂閱地址的代碼。

使用超時,聊天室中的所有人都會每隔30到40秒發送一條簡單的消息,即使他們沒有輸入任何內容,因此這段代碼需要讀取大量數據 - 每40秒至少有2條消息可能更多。

該代碼在EI和Firefox中100%堅實。 但在Chrome中,大約5個讀取失敗了。

當Chrome失敗時,它會超時46秒。

該日志顯示任何時候一個/活動網絡請求未完成。

我已經在這個代碼上爬了3天了,嘗試各種想法。 每當IE和Firefox工作正常而Chrome失敗時。

我看到的一個建議是使呼叫同步 - 但這顯然是不可能的,因為它會長時間鎖定用戶界面。

編輯 - 我有一個部分解決方案:代碼現在是這個

function requestNextBroadcast() {
    // never stops - every reply triggers next. 
    // and silent errors restart via long timeout. 
    getxhr = jQuery.ajax({
        url: "/activity",
        // dataType: 'json',
        data: "id="+channel,
        timeout: <?php echo $delay; ?>,
        error: function(jqXHR, textStatus, errorThrown) {
            window.status="GET error "+textStatus;
            setTimeout(requestNextBroadcast,20);  // try again
        },
        success: function(reply, textStatus, jqXHR) {
            handleRequest(reply);   // this is the normal result. 
            setTimeout(requestNextBroadcast,20); 
        }
    });
}

結果有時會延遲回復,直到$ delay(15000)發生,然后排隊的消息太快到達了。 我一直無法通過這種新安排刪除消息(僅通過netwrok optomisation測試)。

我非常懷疑網絡問題的延遲是什么 - 所有機器都是我真實機器中的虛擬機,並且本地局域網中沒有其他用戶。

編輯2(美國中部時間星期五2:30) - 更改代碼以使用承諾 - 並且操作的POST開始顯示相同的症狀,但接收方開始正常工作! (???? !!! ???)。 這是POST例程 - 它處理一系列請求,以確保一次只有一個請求。

function issuePostNow() {
    // reset heartbeat to dropout to send setTyping(false) in 30 to 40 seconds. 
    clearTimeout(dropoutat);
    dropoutat = setTimeout(function() {sendTyping(false);},  
                           30000 + 10000*Math.random()); 
    // and do send 
    var url = "handlechat.php?";
    if (postQueue.length > 0) {
        postData = postQueue[0];
        var postxhr = jQuery.ajax({ 
            type: 'POST',
            url: url,
            data: postData,
            timeout: 5000
        })
        postxhr.done(function(txt){
            postQueue.shift();  // remove this task
            if ((txt != null) && (txt.length > 0)) {
                alert("Error: unexpected post reply of: "+txt)
            }
            issuePostNow();
        });
        postxhr.fail(function(){
            alert(window.status="POST error "+postxhr.statusText);
            issuePostNow();
        });
    }
}

關於8中的一個動作,對handlechat.php的調用將超時並顯示警報。 警報一旦確定,所有排隊的消息都會到達。

而且我還注意到,在寫出其他人會看到的消息之前,手機呼叫已停止。 我想知道是否可能是一些奇怪的處理會話數據的PHP。 我知道它仔細排隊呼叫,以便會話數據不被破壞,所以我一直小心使用不同的瀏覽器或不同的機器。 只有2個php工作線程,但是php不用於處理/活動或靜態內容的服務。

我也認為它可能是nginx工作者或php處理器的短缺,所以我提出了這些。 現在更難以讓事情失敗 - 但仍然可能。 我的猜測是/ activity調用現在失敗30次,並且根本不丟棄消息。

謝謝你們的投入。


調查結果摘要。

1)Chrome中的一個錯誤已經在代碼中存在了一段時間。
2)幸運的是,可以將錯誤顯示為未發送的POST,並且當它超時時,它會使Chrome處於這樣一種狀態,即重復POST將成功。
3)用於存儲$ .ajax()的返回的變量可以是本地的或全局的。 新的(promises)和舊的格式調用都觸發了bug。
4)我沒有找到工作或避免錯誤的方法。

伊恩

我與Chrome有一個非常相似的問題。 我正在進行Ajax調用,以便每秒從服務器獲取時間。 顯然,Ajax調用必須是異步的,因為如果沒有,它會在超時時凍結接口。 但是,一旦Ajax調用之一失敗,每個后續調用都是如此。 我首先嘗試將超時設置為100毫秒,這在IE和FF中運行良好,但在Chrome中卻沒有。 我最好的解決方案是將類型設置為POST,並為我解決了chrome的錯誤:

   setInterval(function(){ 
      $.ajax({
         url: 'getTime.php',
         type: 'POST',
         async: true,
         timeout: 100,
         success: function() { console.log("success"); },
         error: function() { console.log("error"); }
       });
   }, 1000);

更新:我認為這里的實際根本問題是Chrome的緩存方式。 似乎當一個請求失敗時,該緩存會被緩存,因此后續請求永遠不會發生,因為Chrome會在啟動后續請求之前獲得緩存失敗。 如果您轉到Chrome的開發人員工具並轉到“網絡”標簽並檢查每個正在發出的請求,就可以看到這一點。 在失敗之前,每秒都會對getTime.php發出ajax請求,但是在1次失敗之后,永遠不會啟動后續請求。 因此,以下解決方案對我有用:

   setInterval(function(){ 
      $.ajax({
         url: 'getTime.php',
         cache: false,
         async: true,
         timeout: 100,
         success: function() { console.log("success"); },
         error: function() { console.log("error"); }
       });
   }, 1000);

這里的變化是,我禁止緩存到這個Ajax查詢,但為了這樣做,類型選項必須是GET或HEAD,這就是我刪除' type: 'POST' '的原因(GET是默認的)。

嘗試將您的輪詢功能移動到網絡工作者,以防止鉻合金凍結。 否則你可以嘗試使用jquery對象的ajax .done()。 一個人總是在我的鉻合金。

我覺得getxhr應該以“var”為前綴。 您是否每次都想要一個完全獨立的新請求而不是在成功/失敗處理過程中覆蓋舊請求? 可以解釋為什么添加setTimeout時行為“改進”。 我也可能遺漏了一些東西;)

評論不會格式化代碼,因此重新發布為第二個答案:

我認為Michael Dibbets正在使用$ .ajax.done - 延遲模式將處理推送到事件循環的下一輪,我認為這是需要的行為。 請參閱: http//www.bitstorm.org/weblog/2012-1/Deferred_and_promise_in_jQuery.htmlhttp://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/

我會嘗試這樣的事情:

function requestNextBroadcast() { 
  // never stops - every reply triggers next.
  // and silent errors restart via long timeout.

  getxhr = jQuery.ajax({
    url: "/activity",
    // dataType: 'json',
    data: "id="+channel,
    timeout: <?php echo $delay; ?> 
  });

  getxhr.done(function(reply){
    handleRequest(reply);
  });

  getxhr.fail(function(e){
    window.status="GET error " + e;
  });

  getxhr.always(function(){
    requestNextBroadcast();
  });

注意:我很難找到Promise.done和Promise.fail的回調參數的文檔:(

也許它可以通過改變推模塊設置(有幾個)來解決 - 你能發布這些嗎?

從我的頭頂:

  • 將它設置為區間輪詢,有點可以解決它
  • 並發設置可能會產生一些影響
  • 消息存儲可能用於避免丟失數據

我還會使用類似Charles的東西來查看網絡/應用程序層上究竟發生了什么

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM