Soru JQuery kullanarak Ajax isteklerini iptal etme


JQuery'yi kullanarak nasıl yapabilirim? Ajax isteğini iptal etme / iptal etme cevabı henüz almadım mı?


1637
2018-01-15 12:45


Menşei


Belki sorumu yanlış anladım, ama kullanamazsın $.ajaxStop? - Luke Madhanga
@LukeMadhanga; bence ajaxStop sadece tüm AJAX isteklerinin ne zaman tamamlandığını algılar, istek durmaz. Benim tecrübelerime göre bunu şöyle kullanırsın: $(document).ajaxStop(function(){alert("All done")}). kullanma .abort() en iyi seçenek. - TheCarver


Cevaplar:


JQuery Ajax yöntemlerinin çoğu, bir XMLHttpRequest (veya eşdeğer) nesnesini döndürür, böylece yalnızca kullanabilirsiniz 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ÜNCELLEŞTİRME: JQuery 1.5'den itibaren 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 ve yukarıdaki örnek hala çalışır. Görmek JqXHR Nesnesi (jQuery API belgeleri).

GÜNCELLEME 2: JQuery 3'ten itibaren, ajax yöntemi artık ek metodlarla (iptal gibi) bir söz verir, böylece yukarıdaki kod hala çalışır, ancak döndürülen nesne bir xhr daha fazla Bakın Burada 3.0 blog.

GÜNCELLEME 3: xhr.abort() hala jQuery 3.x üzerinde çalışıyor. Farz etmeyin 2 güncelleyin doğru. JQuery Github deposu hakkında daha fazla bilgi.


1597
2018-01-15 12:56



Tarayıcınızdaki 'stop' düğmesine tıklamak gibi. İsteği iptal eder. Daha sonra başka bir istek için aynı XHR nesnesini yeniden kullanabilirsiniz. - meouw
@brad Maalesef abort sunucuyla kurulan bağlantıyı kapatmıyor, success hala çağrılacak. Bu uzun sorgulama ile Comet uygulamaları için çok sorunlu. - pepkin88
@ErvWalter Önceki olanı iptal eden başka bir istek gönderebilirsiniz. - Asad Saeeduddin
Testlerimde, istek tarayıcıda iptal edilir, ancak jqXHR, status = 0 ve jqXHR, statusMessage = "abort" ile .fail () yöntemi çağrılır. - BJ Safdie
Artık jQuery 3.0 için çalışmayacak blog.jquery.com/2016/01/14/jquery-3-0-beta-released - jcubic


İsteği hatırlayamazsınız, ancak yanıtın göz ardı edileceği bir zaman aşımı değeri belirleyebilirsiniz. Bunu gör sayfa jquery AJAX seçenekleri için. Zaman aşımı süresi aşılırsa hata geri aranacağını düşünürüm. Her AJAX isteğinde zaten bir varsayılan zaman aşımı var.

Ayrıca kullanabilirsiniz ) (Çıkmak İstek nesnesinde yöntem, ancak istemcinin olayı dinlemesini durduracak olmasına karşın, Mayıs ayı büyük olasılıkla sunucunun işlenmesini engellemez.


106
2018-01-15 12:55





Bu bir eşzamanlı olmayan istek, bir kez gönderildiğinde bir şey var.

Sunucunuzun AJAX talebi nedeniyle çok pahalı bir işlem başlatması durumunda, yapabileceğiniz en iyi şey, sunucunuzu iptal isteklerini dinleyecek şekilde açmak ve sunucuyu yaptıklarını durdurmak için bildiren ayrı bir AJAX isteği göndermek.

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


70
2018-01-15 12:56



Bu bağlamda, eşzamansızlık sadece isteğin komut dosyasının akışını kesintiye uğratmadığı anlamına gelir. Tarayıcılar artık isteğin tamamlanmasından önce isteği erken iptal etme olanağına sahiptir. - ElephantHunter
Sunucuya nasıl iptal isteği gönderebiliriz? Sunucunun işlenmeyi durdurma isteğini nasıl anlayacağını anlamıyorum. Bir örnek verebilir misiniz? Teşekkür ederim. - Lucky Soni
@LuckySoni, Elephanthunter sadece müşteri tarafını tartışıyor. Sunucu bir .abort isteğinden etkilenmeyecek - Kloar
@Kloar, istek henüz sunucu tarafından alınmamışsa (f.ex. büyük multpart istekleri), istemci soketi kapatabilir ve sunucu etkilenecektir. - white
PHP, iptal edilen istekleri otomatik olarak kontrol eder ve otomatik olarak da sona erer. görmek php.net/manual/en/function.ignore-user-abort.php - hanshenrik


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 yalnızca müşteri tarafıdır. Sunucu tarafı hala isteği işliyor olabilir. Eğer oturum verileri ile PHP veya ASP gibi bir şey kullanıyorsanız, ajax bitene kadar oturum verileri kilitlenir. Dolayısıyla, kullanıcının web sitesine göz atmaya devam etmesine izin vermek için session_write_close(). Bu, oturumu kaydeder ve kilidini açar, böylece devam etmek için bekleyen diğer sayfalar devam eder. Bu olmadan, kilidin kaldırılması için birkaç sayfa beklenebilir.


62
2018-03-28 11:34





AJAX istekleri, başlatılma sırasına göre tamamlanamayabilir. İptal etmek yerine, seçebilirsiniz aldırmamak En yeni olanı hariç tüm AJAX yanıtları:

  • Sayaç oluştur
  • AJAX isteğini başlattığınızda sayacı artırma
  • İsteğin "damgalanması" için geçerli sayacın değerini kullanın
  • Başarının geri dönüşünde, en son istek olup olmadığını kontrol etmek için pulları sayaçla karşılaştırın

Kodun kaba taslakları:

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 üzerinde demo


45
2018-01-18 12:55





Sadece bu problemi çözmek ve üç farklı yaklaşımı test etmek zorunda kaldık.

  1. Meouw tarafından önerilen isteği iptal eder
  2. Tüm talebi yerine getirmek ancak son gönderimin sonucunu işlemden geçirmek
  3. Bir başkası hala 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ğinden # 3 yaklaşımını kullanmaya karar verdik. Ama jQuery .complete () - yönteminin çağrısını garanti ediyorsa% 100 emin değilim, bu bir kilitlenme durumu oluşturabilir. Testlerimizde böyle bir durumu yeniden üretemedik.


36
2018-03-06 14:29





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

Ama ajax isteğinin boş olup olmadığını kontrol etmek için bir if deyimini kontrol ederseniz çok daha iyi olur.


30
2017-10-15 09:14



Ayrıca bir isteğin zaten çalışıp çalışmadığını kontrol ediyorum, ancak daha hafif olduğu için boole kullanıyorum. - Zesty


mücahit çözümü doğru, ama daha fazla kontrol ile ilgileniyorsanız o zaman deneyebilirsiniz Ajax Yöneticisi eklentisi jQuery için.


19
2018-01-15 15:45



Link öldü ve Web Arşivi'nin enstantaneleri 301 sayfa ... Belirtilen eklentiye benzeyen bir çatal buldum: github.com/aFarkas/Ajaxmanager/blob/master/... - brasofilo


Canlı bir arama çözümü yapıyordum ve en güncel / en güncel taleplerden daha uzun sürebilir bekleyen 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 

11
2017-12-04 14:43





İş parçacığı üzerinde birçok kişi belirttiği gibi, yalnızca istemci tarafında istek iptal edildiğinden, sunucu yine de isteği işleyecektir. Bu, sunucuda gereksiz yükler yaratıyor çünkü ön uçta dinlemeyi bıraktığımız işi yapıyoruz.

Çözmeyi denediğim problem (diğerlerinin de işe yarayabileceği gibi), kullanıcı bir giriş alanında bilgi girdiğinde, Google Anında hissetme türü için istekte bulunmak istedim.

Gereksiz istekleri engellemek ve ön uçun dazlaklığını korumak için şunları 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önderecektir (kendi ihtiyaçlarınız için özelleştirebileceğiniz bir değişken). Burada neler olduğunu anlamakta sorun yaşıyorsanız, günlük xhrCount ve xhrQueue if bloğundan hemen önce konsola.


10
2018-02-03 18:43