Pertanyaan Batalkan permintaan Ajax menggunakan jQuery


Menggunakan jQuery, bagaimana saya bisa membatalkan / membatalkan permintaan Ajax bahwa saya belum menerima tanggapan dari?


1633
2018-01-15 12:45


asal


Jawaban:


Sebagian besar metode jQuery Ajax mengembalikan objek XMLHttpRequest (atau yang setara), jadi Anda cukup menggunakan abort().

Lihat dokumentasi:

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

MEMPERBARUI: Pada jQuery 1.5 objek yang dikembalikan adalah pembungkus untuk objek XMLHttpRequest asli yang disebut jqXHR. Objek ini tampaknya mengekspos semua properti dan metode asli sehingga contoh di atas masih berfungsi. Lihat Objek jqXHR (dokumentasi API jQuery).

PERBARUI 2: Pada jQuery 3, metode ajax sekarang mengembalikan janji dengan metode ekstra (seperti abort), sehingga kode di atas masih berfungsi, meskipun objek yang dikembalikan bukan xhr lagi. Lihat 3.0 blog di sini.

PERBARUI 3: xhr.abort() masih berfungsi di jQuery 3.x. Jangan berasumsi itu perbarui 2 benar. Info lebih lanjut tentang repositori Github jQuery.


1592
2018-01-15 12:56



Anda tidak dapat mengingat permintaan tersebut tetapi Anda dapat menetapkan nilai waktu tunggu yang responsnya akan diabaikan. Lihat ini halaman untuk opsi AJAX jquery. Saya yakin bahwa callback error Anda akan dipanggil jika periode timeout terlampaui. Sudah ada batas waktu default pada setiap permintaan AJAX.

Anda juga bisa menggunakan menggugurkan() metode pada objek permintaan tetapi, sementara itu akan menyebabkan klien berhenti mendengarkan acara, itu mungkin mungkin tidak akan menghentikan server memprosesnya.


106
2018-01-15 12:55



Itu adalah asynchronous permintaan, artinya setelah dikirim keluar sana.

Jika server Anda memulai operasi yang sangat mahal karena permintaan AJAX, hal terbaik yang dapat Anda lakukan adalah membuka server Anda untuk mendengarkan permintaan pembatalan, dan mengirim permintaan AJAX terpisah yang memberi tahu server untuk menghentikan apa pun yang dilakukannya.

Jika tidak, abaikan saja respon AJAX.


70
2018-01-15 12:56



Simpan panggilan yang Anda buat dalam larik, lalu panggil xhr.abort () pada masing-masing.

CAVEAT BESAR: Anda dapat membatalkan permintaan, tetapi itu hanya sisi klien. Sisi server masih bisa memproses permintaan. Jika Anda menggunakan sesuatu seperti PHP atau ASP dengan data sesi, data sesi dikunci sampai ajax selesai. Jadi, untuk memungkinkan pengguna melanjutkan penelusuran situs web, Anda harus menelepon session_write_close(). Ini menyimpan sesi dan membuka kunci sehingga halaman lain yang menunggu untuk melanjutkan akan dilanjutkan. Tanpa ini, beberapa halaman dapat menunggu kunci untuk dihapus.


62
2018-03-28 11:34



Permintaan AJAX mungkin tidak lengkap dalam urutan yang dimulai. Alih-alih membatalkan, Anda dapat memilih untuk mengabaikan semua tanggapan AJAX kecuali yang terbaru:

  • Buat penghitung
  • Menambah penghitung saat Anda memulai permintaan AJAX
  • Gunakan nilai tukar saat ini untuk "mencap" permintaan
  • Dalam callback sukses, bandingkan cap dengan konter untuk memeriksa apakah itu permintaan paling baru

Garis besar kasar kode:

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

Demo di jsFiddle


45
2018-01-18 12:55



Kami hanya harus mengatasi masalah ini dan menguji tiga pendekatan yang berbeda.

  1. membatalkan permintaan seperti yang disarankan oleh @meouw
  2. jalankan semua permintaan tetapi hanya memproses hasil pengiriman terakhir
  3. mencegah permintaan baru selama yang lain masih menunggu

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

Dalam kasus kami, kami memutuskan untuk menggunakan pendekatan # 3 karena menghasilkan lebih sedikit pemuatan untuk server. Tapi saya tidak 100% yakin jika jQuery menjamin panggilan metode .complete () -, ini bisa menghasilkan situasi deadlock. Dalam pengujian kami, kami tidak dapat mereproduksi situasi seperti itu.


36
2018-03-06 14:29



Itu selalu praktik terbaik untuk melakukan sesuatu seperti ini.

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

Tetapi jauh lebih baik jika Anda memeriksa pernyataan if untuk memeriksa apakah permintaan ajax tidak valid atau tidak.


30
2017-10-15 09:14



solusi meouw Benar, tetapi jika Anda tertarik dengan kontrol lebih banyak maka Anda dapat mencoba Plugin Ajax Manager untuk jQuery.


19
2018-01-15 15:45



Saya melakukan solusi pencarian langsung dan diperlukan untuk membatalkan permintaan yang tertunda yang mungkin lebih lama dari permintaan terbaru / terbaru.

Dalam kasus saya, saya menggunakan sesuatu seperti ini:

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



Seperti banyak orang di thread yang mencatat, hanya karena permintaan dibatalkan di sisi klien, server masih akan memproses permintaan. Ini menciptakan beban yang tidak perlu di server karena melakukan pekerjaan yang telah kami berhenti dengarkan di front-end.

Masalah yang saya coba pecahkan (yang mungkin dijalankan orang lain juga) adalah ketika pengguna memasukkan informasi di bidang masukan, saya ingin memecat permintaan untuk jenis perasaan Google Instan.

Untuk menghindari pengaktifan permintaan yang tidak perlu dan untuk mempertahankan sifat kasar dari front-end, saya melakukan hal berikut:

var xhrQueue = [];
var xhrCount = 0;

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

    xhrQueue.push(xhrCount);

    setTimeout(function(){

        xhrCount = ++xhrCount;

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

    }, 150);

});

Ini pada dasarnya akan mengirim satu permintaan setiap 150ms (variabel yang dapat Anda sesuaikan untuk kebutuhan Anda sendiri). Jika Anda mengalami kesulitan memahami apa yang sebenarnya terjadi di sini, log xhrCount dan xhrQueue ke konsol tepat sebelum blok if.


10
2018-02-03 18:43