JQuery kullanarak Ajax isteklerini iptal etme


1827

JQuery kullanarak, henüz yanıt almadığım bir Ajax isteğini nasıl iptal edebilir / iptal edebilirim ?


2
Belki soruyu yanlış anladım, ama sadece kullanamaz $.ajaxStopmısın?
Luke Madhanga

17
@LukeMadhanga; Bence ajaxStopyalnızca tüm AJAX istekleri tamamlandığında, bu bir istek durmaz algılar. Tecrübelerime göre, bu gibi kullanabilirsiniz olacaktır: $(document).ajaxStop(function(){alert("All done")}). Kullanmak .abort()en iyi seçenektir.
TheCarver

Yanıtlar:


1744

JQuery Ajax yöntemlerinin çoğu bir XMLHttpRequest (veya eşdeğeri) nesnesini döndürür, böylece yalnızca abort() .

Belgelere bakın:

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()

GÜNCELLEME: jQuery 1.5 itibariyle döndürülen nesne, jqXHR adlı yerel XMLHttpRequest nesnesi için bir sarıcıdır. Bu nesne, tüm yerel özellikleri ve yöntemleri ortaya çıkarır, böylece yukarıdaki örnek hala çalışır. Bkz . JqXHR Nesnesi (jQuery API belgeleri).

GÜNCELLEME 2: jQuery 3'ten itibaren, ajax yöntemi artık ekstra yöntemlerle (iptal gibi) bir vaat döndürür, bu nedenle yukarıdaki kod yine de çalışır, ancak döndürülen nesne artık değildir xhr. 3.0 bloguna buradan bakın .

GÜNCELLEME 3 : xhr.abort()hala jQuery 3.x üzerinde çalışıyor. Güncelleme 2'nin doğru olduğunu varsaymayın . JQuery Github repository hakkında daha fazla bilgi .


12
Bu, tarayıcınızdaki 'durdur' düğmesini tıklamak gibidir. İsteği iptal eder. Daha sonra aynı XHR nesnesini başka bir istek için yeniden kullanabilirsiniz.
meouw

65
@brad Ne yazık ki, sunucuyla abortkurulan bir bağlantıyı kapatmaz, bu yüzden successyine de çağrılır. Bu uzun kuyruklu Comet uygulamaları için çok sorunlu.
pepkin88

6
@ErvWalter Öncekini iptal eden başka bir istek gönderebilirsiniz.
Asad Saeeduddin

8
Testlerimde, istek tarayıcıda iptal edildi, ancak .fail () yöntemi bir jqXHR, status = 0 ve jqXHR, statusMessage = "abort" ile çağrıldı
BJ Safdie

9
.abort()jQuery 3.2.1'de hala çalışıyor. Bir jQuery çekirdek ekip üyesi tarafından ilgili bir github sorununda yapılan bu yorum , bu cevabın yanlış olduğunu ve bunun .abort() kaldırılmadığını ima ediyor gibi görünüyor .
alarive

117

İsteği hatırlayamazsınız ancak yanıtın yok sayılması için bir zaman aşımı değeri ayarlayabilirsiniz. Bu sayfaya bakınJquery AJAX seçenekleri için . Zaman aşımı süresi aşılırsa hata geri aramanızın çağrılacağına inanıyorum. Her AJAX isteğinde zaten varsayılan bir zaman aşımı var.

İstek nesnesindeki abort () yöntemini de kullanabilirsiniz, ancak istemcinin olayı dinlemesini durdurmasına neden olsa da , muhtemelen sunucunun işlemesini durduramayabilir.


74

Bu bir var asenkron istek, yani gönderildikten sonra dışarıda.

Sunucunuzun AJAX isteği nedeniyle çok pahalı bir işlem başlatması durumunda, yapabileceğiniz en iyi şey, iptal isteklerini dinlemek için sunucunuzu açmak ve ne yaptığını durdurması için sunucuya bildiren ayrı bir AJAX isteği göndermektir.

Aksi takdirde, AJAX yanıtını dikkate almayın.


48
Bu bağlamda, zaman uyumsuz istek sadece komut dosyasının akışını kesintiye uğratmaz anlamına gelir. Tarayıcılar artık istek tamamlanmadan isteği erken bırakma olanağına sahiptir.
ElephantHunter

4
Sunucuya nasıl iptal isteği gönderebiliriz? Sunucunun hangi isteği işlemeyi durdurduğunu nasıl bileceğini anlamıyorum? Bir örnek verebilir misiniz? Teşekkür ederim.
Şanslı Soni

3
@LuckySoni, Elephanthunter sadece müşteri tarafında tartışıyor. Sunucu bir .abort isteğinden etkilenmeyecek
Kloar

4
@Kloar, istek henüz sunucu tarafından alınmazsa (örn. Büyük çok bölümlü istekler), istemci soketi kapatabilir ve sunucu etkilenir.
beyaz

4
PHP iptal edilen istekleri otomatik olarak kontrol eder ve otomatik olarak da sona erer. bkz. php.net/manual/tr/function.ignore-user-abort.php
hanshenrik

68

Bir dizide yaptığınız aramaları kaydedin, ardından her birinde xhr.abort () öğesini arayın.

BÜYÜK CAVEAT: Bir isteği iptal edebilirsiniz, ancak bu sadece istemci tarafıdır. Sunucu tarafı hala isteği işliyor olabilir. Oturum verileriyle PHP veya ASP gibi bir şey kullanıyorsanız, oturum verileri ajax bitene kadar kilitlenir. Bu nedenle, kullanıcının web sitesine göz atmaya devam etmesine izin vermek için session_write_close () öğesini çağırmanız gerekir . Bu, oturumu kaydeder ve devam etmeyi bekleyen diğer sayfaların devam etmesi için kilidini açar. Bu olmadan, kilidin kaldırılmasını birkaç sayfa bekleyebilir.


bir öncekini her zaman iptal ettiğinden, bunu her zaman yapamaz mısın? (ve bir dizi kullanmaya gerek yok)
nonopolarity

60

AJAX istekleri başlatıldıkları sırada tamamlanamayabilir. İptal etmek yerine , en sonuncusu hariç tüm AJAX yanıtlarını yok saymayı seçebilirsiniz :

  • Sayaç oluşturma
  • AJAX isteğini başlattığınızda sayacı artırın
  • İsteği "damgalamak" için sayacın geçerli değerini kullanın
  • Başarılı geri aramada, en son talep olup olmadığını kontrol etmek için damgayı sayaçla karşılaştırın

Kodun kaba taslağı:

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'da demo


Bir XHR isteğini iptal etme uyarıları nedeniyle (bu sayfadaki diğer yorumlara bakın), bu muhtemelen en iyi ve en basit seçenektir.
Quinn Comendant

41

Bu sorunu çözmek için üç farklı yaklaşımı test ettik.

  1. @meouw tarafından önerilen isteği iptal eder
  2. yalnızca son gönderimin sonucunu işler ancak tüm istekleri yerine getirir
  3. başka bir tane beklemede olduğu sürece yeni istekleri engeller

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" />

Bizim durumumuzda, sunucu için daha az yük ürettiği için # 3 yaklaşımını kullanmaya karar verdik. Ancak jQuery .complete () - yönteminin çağrısını garanti ederse% 100 emin değilim, bu bir kilitlenme durumu üretebilir. Testlerimizde böyle bir durumu yeniden üretemedik.


36

Böyle bir şey yapmak her zaman en iyi uygulamadır.

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);
    });

Ancak, ajax isteğinin boş olup olmadığını kontrol etmek için bir if ifadesini kontrol etmeniz çok daha iyidir.


2
Ayrıca bir isteğin zaten çalışıp çalışmadığını kontrol ediyorum, ancak daha açık olduğu için bir boole kullanıyorum.
Lütfen tıklayınız

15

Sadece xhr'i arayın. jquery ajax nesnesi veya yerel XMLHTTPRequest nesnesi olsun abort () .

misal:

//jQuery ajax
$(document).ready(function(){
    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);

13

Ben canlı bir arama çözümü yapıyordum ve son / en güncel istek daha uzun sürmüş olabilir bekleyen istekleri iptal etmek gerekiyordu.

Benim durumumda böyle bir şey kullandım:

//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 

12

İş parçacığındaki birçok kişinin belirttiği gibi, istek istemci tarafında iptal edildiğinden, sunucu yine de isteği işleyecektir. Bu, sunucuda gereksiz yük oluşturur çünkü ön uçta dinlemeyi bıraktığımız işleri yapıyor.

Çözmeye çalıştığım sorun (diğerlerinin de çalışabileceği), kullanıcı bir girdi alanına bilgi girdiğinde, Google Anında Arama hissi için bir istek göndermek istediğimdir.

Gereksiz istekleri yerine getirmekten kaçınmak ve kullanıcı arabiriminin gizliliğini korumak için aşağıdakileri yaptım:

var xhrQueue = [];
var xhrCount = 0;

$('#search_q').keyup(function(){

    xhrQueue.push(xhrCount);

    setTimeout(function(){

        xhrCount = ++xhrCount;

        if (xhrCount === xhrQueue.length) {
            // Fire Your XHR //
        }

    }, 150);

});

Bu aslında her 150 ms'de bir istek gönderir (kendi ihtiyaçlarınıza göre özelleştirebileceğiniz bir değişken). Burada tam olarak ne olduğunu anlamakta güçlük çekiyorsanız , if bloğundan hemen önce oturum açın xhrCountve xhrQueuekonsola gidin.


11

Örneğin, ajax.abort () yöntemini kullanın, örneğin bunun gibi başka bir istek göndermeden önce beklemedeki ajax isteklerini iptal edebilirsiniz.

//check for existing ajax request
if(ajax){ 
 ajax.abort();
 }
//then you make another ajax request
$.ajax(
 //your code here
  );

11

Bunu kullanarak herhangi bir sürekli ajax çağrısını iptal edebilirsiniz.

<input id="searchbox" name="searchbox" type="text" />

<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>

<script type="text/javascript">
     var request = null;
        $('#searchbox').keyup(function () {
            var id = $(this).val();
            request = $.ajax({
                type: "POST", //TODO: Must be changed to POST
                url: "index.php",
                data: {'id':id},
                success: function () {

                },
                beforeSend: function () {
                    if (request !== null) {
                        request.abort();
                    }
                }
            });
        });

</script>

10

bunu yapmak için güvenilir bir yolu yoktur, ve istek devam ederken ben bile denemek olmaz; Sadece makul tepki yöntemi nedir görmezden yanıtı.

çoğu durumda, bu gibi durumlarda olabilir: bir kullanıcı art arda birçok XHR'yi tetikleyen bir düğmeyi çok sık tıklar, burada birçok seçeneğiniz vardır, XHR dönene kadar düğmeyi engelle veya başka bir ipucu çalışırken yeni XHR'yi tetiklemeyin kullanıcı geriye yaslanmalı - veya beklemede olan XHR yanıtı dışında kalanları atmalıdır.


7

Aşağıdaki kod, bir Ajax isteğinin başlatılmasını ve iptal edilmesini gösterir:

function libAjax(){
  var req;
  function start(){

  req =    $.ajax({
              url: '1.php',
              success: function(data){
                console.log(data)
              }
            });

  }

  function stop(){
    req.abort();
  }

  return {start:start,stop:stop}
}

var obj = libAjax();

 $(".go").click(function(){


  obj.start();


 })



 $(".stop").click(function(){

  obj.stop();


 })
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" class="go" value="GO!" >
   <input type="button" class="stop" value="STOP!" >

5
Lütfen bunun soruyu nasıl çözdüğüne ilişkin bir açıklama yapın. Bu OP ve gelecekteki diğer araştırmacılara yardımcı olacaktır.
SnareChops

5

Yoklama sorunu yaşadım ve sayfa kapatıldıktan sonra anket devam etti, bu yüzden ajax isteğini öldürdüğüm halde, kullanıcı kapanışından sonraki 50 saniye boyunca bir mysql değeri ayarlandığından bir güncelleme kaçırır. bir var ayarlamak için $ _SESSION kullanmak etrafında sona erdi ve yeni bir başlayana kadar ankette kendini güncellemek olmaz, bu yüzden yaptığım şey ben 0 = offpage olarak benim veritabanında bir değer olarak ayarlandı yoklama Bu satırı sorgulayıp false döndürürüm; yoklamada sorgulama yapmak 0 olduğunda mevcut değerleri açıkça alacaktır ...

Umarım bu yardımcı olmuştur


5

xhr.abort(); Sayfanın yeniden yüklenmesine neden olursa ,

Ardından, onreadystatechangeaşağıdakileri önlemek için iptal etmeden önce ayarlayabilirsiniz :

// ↓ prevent page reload by abort()
xhr.onreadystatechange = null;
// ↓ may cause page reload
xhr.abort();

4

Önceden tanımlanmış bir bekleme süresi içinde veri sunucudan döndürülmezse, AJAX isteğinin nasıl iptal edileceğini gösteren bir demo paylaştım .

HTML:

<div id="info"></div>

JS KODU:

var isDataReceived= false, waitTime= 1000; 
$(function() {
    // Ajax request sent.
     var xhr= $.ajax({
      url: 'http://api.joind.in/v2.1/talks/10889',
      data: {
         format: 'json'
      },     
      dataType: 'jsonp',
      success: function(data) {      
        isDataReceived= true;
        $('#info').text(data.talks[0].talk_title);        
      },
      type: 'GET'
   });
   // Cancel ajax request if data is not loaded within 1sec.
   setTimeout(function(){
     if(!isDataReceived)
     xhr.abort();     
   },waitTime);   
});

1
$.ajaxtimeoutkendi seçeneğinizi yazmanıza gerek kalmadan bir seçenek sunar. Sadece kullanın ..., data: {...}, timeout: waitTime,....
Bram Vanroy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.