javascript - xhr - xmlhttprequest stop




使用jQuery中止Ajax請求 (12)

使用jQuery,我如何取消/中止我還沒有收到響應的Ajax請求


AJAX請求可能無法按照它們開始的順序完成。 除了中止外,您可以選擇忽略除最近一次之外的所有AJAX響應:

  • 創建一個計數器
  • 當您啟動AJAX請求時增加計數器
  • 使用計數器的當前值來“戳記”請求
  • 在成功回調中,將標記與計數器進行比較以檢查它是否是最近的請求

代碼粗略概述:

var xhrCount = 0;
function sendXHR() {
    // sequence number for the current invocation of function
    var seqNumber = ++xhrCount;
    $.post("/echo/json/", { delay: Math.floor(Math.random() * 5) }, function() {
        // this works because of the way closures work
        if (seqNumber === xhrCount) {
            console.log("Process the response");
        } else {
            console.log("Ignore the response");
        }
    });
}
sendXHR();
sendXHR();
sendXHR();
// AJAX requests complete in any order but only the last 
// one will trigger "Process the response" message

在jsFiddle上演示



保存你在一個數組中所做的調用,然後分別調用xhr.abort()。

巨大的CAVEAT:您可以放棄請求,但這只是客戶端。 服務器端可能仍然在處理請求。 如果您使用PHP或ASP等會話數據,會話數據將被鎖定,直到ajax完成。 因此,要允許用戶繼續瀏覽網站,您必須調用session_write_close ()。 這會保存會話並將其解鎖,以等待繼續的其他頁面繼續。 沒有這個,幾個頁面可能正在等待鎖被刪除。


做這樣的事情總是最好的做法。

var $request;
if ($request != null){ 
    $request.abort();
    $request = null;
}

$request = $.ajax({
    type : "POST", //TODO: Must be changed to POST
    url : "yourfile.php",
    data : "data"
    }).done(function(msg) {
        alert(msg);
    });

但是,如果您檢查if語句來檢查ajax請求是否為null,會好很多。


只需致電xhr。 abort()不管它是jquery ajax對像還是本機XMLHTTPRequest對象。

例:

//jQuery ajax
$(document).ready(
    var xhr = $.get('/server');
    setTimeout(function(){xhr.abort();}, 2000);
);

//native XMLHTTPRequest
var xhr = new XMLHttpRequest();
xhr.open('GET','/server',true);
xhr.send();
setTimeout(function(){xhr.abort();}, 2000);

大多數jQuery Ajax方法返回一個XMLHttpRequest(或等效的)對象,所以你可以使用abort()

請參閱文檔:

  • 中止方法MSDN )。 取消當前的HTTP請求。
  • abort()MDN )。 如果請求已經發送,則此方法將中止請求。
var xhr = $.ajax({
    type: "POST",
    url: "some.php",
    data: "name=John&location=Boston",
    success: function(msg){
       alert( "Data Saved: " + msg );
    }
});

//kill the request
xhr.abort()

更新:從jQuery 1.5開始,返回的對像是一個名為jqXHR的原生XMLHttpRequest對象的包裝器。 這個對像似乎公開了所有的本地屬性和方法,所以上面的例子仍然有效。 請參閱jqXHR對象 (jQuery API文檔)。

更新2:截至jQuery 3,ajax方法返回一個沒有額外方法的承諾(如中止),所以這將不再工作。 在這裡查看3.0博客 。 解決這個問題的一個方法是通過xhr屬性來控制xhr對象。 這是一個簡單的例子:

var xhr = new window.XMLHttpRequest();
var request = $.ajax({
    url : url,
    xhr : function(){
        return xhr;
    }
});
xhr.abort();

您無法記起請求,但可以設置一個超時值,之後響應將被忽略。 看到這個page的jQuery AJAX選項。 我相信如果超時超時,你的錯誤回調將被調用。 每個AJAX請求都有一個默認的超時時間。

您也可以在請求對像上使用abort()方法,但是,雖然它會導致客戶端停止監聽事件,但它可能不會阻止服務器處理它。


我們只需要解決這個問題並測試了三種不同的方法。

  1. 根據@meouw的建議取消請求
  2. 執行所有請求,但僅處理上次提交的結果
  3. 只要另一個仍在等待,就可以阻止新的請求

var Ajax1 = {
  call: function() {
    if (typeof this.xhr !== 'undefined')
      this.xhr.abort();
    this.xhr = $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        //process response
      }
    });
  }
};
var Ajax2 = {
  counter: 0,
  call: function() {
    var self = this,
      seq = ++this.counter;
    $.ajax({
      url: 'your/long/running/request/path',
      type: 'GET',
      success: function(data) {
        if (seq === self.counter) {
          //process response
        }
      }
    });
  }
};
var Ajax3 = {
  active: false,
  call: function() {
    if (this.active === false) {
      this.active = true;
      var self = this;
      $.ajax({
        url: 'your/long/running/request/path',
        type: 'GET',
        success: function(data) {
          //process response
        },
        complete: function() {
          self.active = false;
        }
      });
    }
  }
};
$(function() {
  $('#button').click(function(e) {
    Ajax3.call();
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="button" type="button" value="click" />

在我們的例子中,我們決定使用方法#3,因為它為服務器產生較少的負載。 但是我不能100%確定jQuery是否保證了.complete()方法的調用,這可能會導致死鎖情況。 在我們的測試中,我們無法重現這種情況。


我正在做一個實時搜索解決方案,並需要取消可能需要比最新/最新請求更長的未決請求。

在我的情況下,我使用了這樣的東西:

//On document ready
var ajax_inprocess = false;

$(document).ajaxStart(function() {
ajax_inprocess = true;
});

$(document).ajaxStop(function() {
ajax_inprocess = false;
});

//Snippet from live search function
if (ajax_inprocess == true)
{
    request.abort();
}
//Call for new request 

我遇到了輪詢的問題,一旦頁面關閉,投票繼續進行,因此在我的原因中,用戶會錯過更新,因為在關閉頁面後的下一個50秒內會設置一個mysql值,即使我殺了ajax請求,我在使用$ _SESSION來設置一個var時,它不會在它自己的poll中更新,直到它結束並且一個新的開始,所以我所做的就是在我的數據庫中將值設置為0 = offpage,而我輪詢我查詢該行並返回false; 當它為0時,在輪詢中查詢會明顯得到當前值......

我希望這有助於


沒有可靠的方法來做到這一點,而且一旦請求在移動中,我甚至不會去嘗試; 唯一合理反應的方法是忽略回應。

在大多數情況下,它可能發生在如下情況中:用戶在按鈕上點擊過多會觸發許多連續的XHR,這裡有很多選項,要么阻止按鈕直到返回XHR,要么在另一個運行提示時甚至不觸發新的XHR用戶靠後 - 或放棄任何未決的XHR響應,但最近。


這是一個異步請求,意思是一旦它被發送出去。

如果您的服務器由於AJAX請求而開始非常昂貴的操作,那麼您可以做的最好的方法是打開服務器以偵聽取消請求,並發送單獨的AJAX請求,通知服務器停止正在執行的操作。

否則,只需忽略AJAX響應。





ajax