2017-10-19 63 views
0

我想測試ajax請求是否相同,因此可以中止或採取其他警報措施?在刷新時避免完全相同的客戶端ajax請求

實際上,客戶端可以通過幾個表單元素來改變請求,然後點擊刷新按鈕。

我已經做了很差的嘗試來捕捉相同的請求。需要保持定時器刷新功能。

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script> 

<script type="text/javascript"> 

    var current_request_id = 0; 
    var currentRequest = null; 
    var lastSuccessfulRequest = null; 

    function refreshTable() { 
     $('#select').html('Loading'); 
     window.clearTimeout(timer); 

     //MY CATCH FOR DUPLICATE REQUEST NEEDS WORK 
     if (lastSuccessfulRequest == currentRequest) 
     { 
      //currentRequest.abort(); 
      alert('Duplicate query submitted. Please update query before resubmission.'); 
     } 

     var data = { 
      "hide_blanks": $("#hide_blanks").prop('checked'), 
      "hide_disabled": $("#hide_disabled").prop('checked'), 
     }; 

     json_data = JSON.stringify(data); 

     current_request_id++; 
     currentRequest = $.ajax({ 
      url: "/calendar_table", 
      method: "POST", 
      data: {'data': json_data}, 
      request_id: current_request_id, 
      beforeSend : function(){ 
       if(currentRequest != null) { 
        currentRequest.abort(); 
       } 
      }, 
      success: function(response) { 
       if (this.request_id == current_request_id) { 
        $("#job_table").html(response); 
        $("#error_panel").hide(); 
        setFixedTableHeader(); 
       } 
      }, 
      error: function(xhr) { 
       if (this.request_id == current_request_id) { 
        $("#error_panel").show().html("Error " + xhr.status + ": " + xhr.statusText + "<br/>" + xhr.responseText.replace(/(?:\r\n|\r|\n)/g, "<br/>")); 
       } 
      }, 
      complete: function(response) { 
       if (this.request_id == current_request_id) { 
        $("#select").html("Refresh"); 
        window.clearTimeout(timer); 
        stopRefreshTable(); 
        window.refreshTableTimer = window.setTimeout(refreshTable, 10000); 

        lastSuccessfulRequest = currentRequest; 
       } 
      } 
     }); 
    } 




    //TIMER STUFF TO refreshTable() 
    //THIS SECTION WORKS FINE 
    var startDate = new Date(); 
    var endDate = new Date(); 
    var timer = new Date(); 
    function startRefreshTable() { 
     if(!window.refreshTableTimer) { 
      window.refreshTableTimer = window.setTimeout(refreshTable, 0); 
     } 
    } 
    function stopRefreshTable() { 
     if(window.refreshTableTimer) { 
      self.clearTimeout(window.refreshTableTimer); 
     } 
     window.refreshTableTimer = null; 
    } 
    function resetActive(){ 
     clearTimeout(activityTimeout); 
     activityTimeout = setTimeout(inActive, 300000); 
     startRefreshTable(); 
    } 

    function inActive(){ 
     stopRefreshTable(); 
    } 
    var activityTimeout = setTimeout(inActive, 300000); 
    $(document).bind('mousemove click keypress', function(){resetActive()}); 

</script> 


<input type="checkbox" name="hide_disabled" id="hide_disabled" onchange="refreshTable()">Hide disabled task<br> 
<br><br> 
<button id="select" type="button" onclick="refreshTable();">Refresh</button> 
+1

「是相同的」......與......完全相同?之前的請求?以前的任何請求?還有別的嗎?從什麼意義上來說是相同的來自同一個用戶?完全相同的參數?相同的標題?請澄清您的確切要求。你現在這樣做的方式很幼稚。 $ .ajax返回一個Deferred對象,你無法用任何有意義的方式與另一個對象進行真正的「平等」比較,也不會告訴你任何關於請求的內容 - 它是爲你添加回調而設計的,以便處理響應。一旦你澄清了你的意思,我們可以找到一個更好的方法來做到這一點 – ADyson

+1

另外一個方面說明:jQuery的'.bind'被jQuery 1.7中的'.on'取代,現在完全棄用。應該沒有理由繼續使用它,或者更糟糕的是,將其用於新代碼。 http://api.jquery.com/bind/ – ADyson

+0

當然,有一種方法可以在不發佈一百行代碼的情況下表達您的觀點。閱讀並遵循[mcve]。 – Tomalak

回答

0

我會使用的.ajaxSend.ajaxSuccess全球處理的權力。

我們將使用ajaxSuccess來存儲緩存,並且ajaxSend會先嚐試讀取它,如果成功,它將立即觸發請求的成功處理程序,並中止即將完成的請求。否則它會讓它成爲...

var ajax_cache = {}; 
function cache_key(settings){ 
    //Produce a unique key from settings object; 
    return settings.url+'///'+JSON.encode(settings.data); 
} 
$(document).ajaxSuccess(function(event,xhr,settings,data){ 
    ajax_cache[cache_key(settings)] = {data:data}; 
    // Store other useful properties like current timestamp to be able to prune old cache maybe? 
}); 
$(document.ajaxSend(function(event,xhr,settings){ 
    if(ajax_cache[cache_key(settings)]){ 
     //Add checks for cache age maybe? 
     //Add check for nocache setting to be able to override it? 
     xhr.abort(); 
     settings.success(ajax_cache[cache_key(settings)].data); 
    } 
}); 

我在這裏證明是一個非常幼稚的,但功能的方法來你的問題。這有利於使你可以擁有的每一個Ajax調用都能工作,而無需改變它們。您需要在此基礎上進行構建以考慮失敗,並確保從緩存命中發出的請求流產不會被分派以中止處理程序。

0

這裏一個有效的選項是JSON.Stringify()對象並比較字符串。如果對象相同,則生成的序列化字符串應該相同。

如果您直接從響應中使用已經過JSON化的字符串,則可能會導致輕微的差異,因此您必須通過測試進行雙重檢查。

此外,如果您試圖弄清楚如何在跨頁加載中使用它,請使用localStorage.setItem("lastSuccessfulRequest", lastSuccessfulRequest)localStorage.getItem("lastSuccessfulRequest")。 (如果沒有,請告訴我,我將刪除此內容。)