ฉันมีปัญหาเมื่อส่งแบบฟอร์มคำขอ ajax ทั้งหมดที่ใช้งานล้มเหลวและทำให้เกิดข้อผิดพลาด
วิธีหยุดคำขอ ajax ที่แอ็คทีฟทั้งหมดใน jQuery โดยไม่มีเหตุการณ์ข้อผิดพลาดทริกเกอร์
ฉันมีปัญหาเมื่อส่งแบบฟอร์มคำขอ ajax ทั้งหมดที่ใช้งานล้มเหลวและทำให้เกิดข้อผิดพลาด
วิธีหยุดคำขอ ajax ที่แอ็คทีฟทั้งหมดใน jQuery โดยไม่มีเหตุการณ์ข้อผิดพลาดทริกเกอร์
คำตอบ:
ทุกครั้งที่คุณสร้างคำขอ ajax คุณสามารถใช้ตัวแปรเพื่อจัดเก็บ:
var request = $.ajax({
type: 'POST',
url: 'someurl',
success: function(result){}
});
จากนั้นคุณสามารถยกเลิกการร้องขอ:
request.abort();
คุณสามารถใช้อาร์เรย์ติดตามคำขออาแจ็กซ์ที่ค้างอยู่ทั้งหมดและยกเลิกพวกเขาหากจำเป็น
ตัวอย่างต่อไปนี้ช่วยให้คุณรักษารายการ ( พูล ) ของคำขอและยกเลิกทั้งหมดหากจำเป็น ที่ดีที่สุดที่จะอยู่ใน<HEAD>
html ของคุณก่อนที่จะมีการโทร AJAX อื่น ๆ
<script type="text/javascript">
$(function() {
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(i, jqXHR) { // cycle through list of recorded connection
jqXHR.abort(); // aborts connection
$.xhrPool.splice(i, 1); // removes from list by index
});
}
$.ajaxSetup({
beforeSend: function(jqXHR) { $.xhrPool.push(jqXHR); }, // annd connection to list
complete: function(jqXHR) {
var i = $.xhrPool.indexOf(jqXHR); // get index for current connection completed
if (i > -1) $.xhrPool.splice(i, 1); // removes from list by index
}
});
})
</script>
Object doesn't support property or method 'indexOf'
? ฉันสงสัยว่ามันอาจจะstackoverflow.com/a/2608601/181971หรืออาจจะเพียงแค่การแลกเปลี่ยนเพื่อstackoverflow.com/a/2608618/181971 ?
การใช้ajaxSetup ไม่ถูกต้องดังที่บันทึกไว้ในหน้าเอกสาร มันตั้งค่าเริ่มต้นเท่านั้นและหากคำขอบางอย่างแทนที่พวกเขาจะมีระเบียบ
ฉันไปงานปาร์ตี้ช้า แต่สำหรับการอ้างอิงในอนาคตหากใครบางคนกำลังมองหาวิธีการแก้ปัญหาเดียวกันนี่คือฉันไปที่มันแรงบันดาลใจจากและส่วนใหญ่เหมือนคำตอบก่อนหน้า แต่สมบูรณ์มากขึ้น
// Automatically cancel unfinished ajax requests
// when the user navigates elsewhere.
(function($) {
var xhrPool = [];
$(document).ajaxSend(function(e, jqXHR, options){
xhrPool.push(jqXHR);
});
$(document).ajaxComplete(function(e, jqXHR, options) {
xhrPool = $.grep(xhrPool, function(x){return x!=jqXHR});
});
var abort = function() {
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
};
var oldbeforeunload = window.onbeforeunload;
window.onbeforeunload = function() {
var r = oldbeforeunload ? oldbeforeunload() : undefined;
if (r == undefined) {
// only cancel requests if there is no prompt to stay on the page
// if there is a prompt, it will likely give the requests enough time to finish
abort();
}
return r;
}
})(jQuery);
นี่คือสิ่งที่ฉันกำลังใช้เพื่อให้บรรลุ
$.xhrPool = [];
$.xhrPool.abortAll = function() {
_.each(this, function(jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
หมายเหตุ: _.each ของ underscore.js มีอยู่ แต่เห็นได้ชัดว่าไม่จำเป็น ฉันขี้เกียจและฉันไม่ต้องการเปลี่ยนเป็น $ .each () 8P
aboutAll
ควรลบองค์ประกอบออกจากอาร์เรย์ เมื่อคำขอเสร็จสิ้นก็ควรลบตัวเองออกจากรายการ
ให้แต่ละ xhr ร้องขอ id ที่ไม่ซ้ำกันและเก็บการอ้างอิงวัตถุในวัตถุก่อนที่จะส่ง ลบการอ้างอิงหลังจากการร้องขอ xhr เสร็จสมบูรณ์
หากต้องการยกเลิกการร้องขอทั้งหมดได้ตลอดเวลา:
$.ajaxQ.abortAll();
ส่งคืนรหัสประจำตัวที่ไม่ซ้ำกันของคำขอที่ถูกยกเลิก เพื่อการทดสอบเท่านั้น
ฟังก์ชั่นการทำงาน:
$.ajaxQ = (function(){
var id = 0, Q = {};
$(document).ajaxSend(function(e, jqx){
jqx._id = ++id;
Q[jqx._id] = jqx;
});
$(document).ajaxComplete(function(e, jqx){
delete Q[jqx._id];
});
return {
abortAll: function(){
var r = [];
$.each(Q, function(i, jqx){
r.push(jqx._id);
jqx.abort();
});
return r;
}
};
})();
ส่งคืนวัตถุที่มีฟังก์ชั่นเดียวซึ่งสามารถใช้เพื่อเพิ่มฟังก์ชั่นมากขึ้นเมื่อจำเป็น
ฉันพบว่ามันง่ายเกินไปสำหรับหลายคำขอ
ขั้นที่ 1:กำหนดตัวแปรที่ด้านบนของหน้า:
xhrPool = []; // no need to use **var**
ขั้นที่ 2:ตั้งไว้ก่อนส่งในคำขอ ajax ทั้งหมด:
$.ajax({
...
beforeSend: function (jqXHR, settings) {
xhrPool.push(jqXHR);
},
...
ขั้นที่ 3:ใช้ตามที่คุณต้องการ:
$.each(xhrPool, function(idx, jqXHR) {
jqXHR.abort();
});
ฉันขยาย mkmurray และคำตอบ SpYk3HH ด้านบนเพื่อให้ xhrPool.abortAll สามารถยกเลิกการร้องขอที่รอดำเนินการทั้งหมดของ URL ที่กำหนด :
$.xhrPool = [];
$.xhrPool.abortAll = function(url) {
$(this).each(function(i, jqXHR) { // cycle through list of recorded connection
console.log('xhrPool.abortAll ' + jqXHR.requestURL);
if (!url || url === jqXHR.requestURL) {
jqXHR.abort(); // aborts connection
$.xhrPool.splice(i, 1); // removes from list by index
}
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR); // add connection to list
},
complete: function(jqXHR) {
var i = $.xhrPool.indexOf(jqXHR); // get index for current connection completed
if (i > -1) $.xhrPool.splice(i, 1); // removes from list by index
}
});
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
console.log('ajaxPrefilter ' + options.url);
jqXHR.requestURL = options.url;
});
การใช้งานเหมือนกันยกเว้นว่า abortAll สามารถเลือกที่จะยอมรับ URL เป็นพารามิเตอร์และจะยกเลิกเฉพาะการโทรไปยัง URL นั้น
ฉันมีปัญหากับโค้ดของ andy แต่มันให้ความคิดที่ดีกับฉัน ปัญหาแรกคือเราควรจะปิดวัตถุ jqXHR ใด ๆ ที่เสร็จสมบูรณ์ ฉันต้องแก้ไขฟังก์ชัน abortAll ด้วย นี่คือรหัสการทำงานสุดท้ายของฉัน:
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(idx, jqXHR) {
jqXHR.abort();
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
}
});
$(document).ajaxComplete(function() {
$.xhrPool.pop();
});
ฉันไม่ชอบวิธี ajaxComplete () ในการทำสิ่งต่าง ๆ ไม่ว่าฉันจะพยายามกำหนดค่า. AjaxSetup มันไม่ทำงาน
ฉันได้อัปเดตรหัสเพื่อให้ใช้งานได้สำหรับฉัน
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(idx, jqXHR) {
jqXHR.abort();
});
$(this).each(function(idx, jqXHR) {
var index = $.inArray(jqXHR, $.xhrPool);
if (index > -1) {
$.xhrPool.splice(index, 1);
}
});
};
$.ajaxSetup({
beforeSend: function(jqXHR) {
$.xhrPool.push(jqXHR);
},
complete: function(jqXHR) {
var index = $.inArray(jqXHR, $.xhrPool);
if (index > -1) {
$.xhrPool.splice(index, 1);
}
}
});
โยนหมวกของฉันเข้าข้อเสนอabort
และremove
วิธีการต่อต้านxhrPool
แถวลำดับและไม่น่าจะมีปัญหากับการajaxSetup
แทนที่
/**
* Ajax Request Pool
*
* @author Oliver Nassar <onassar@gmail.com>
* @see http://stackoverflow.com/questions/1802936/stop-all-active-ajax-requests-in-jquery
*/
jQuery.xhrPool = [];
/**
* jQuery.xhrPool.abortAll
*
* Retrieves all the outbound requests from the array (since the array is going
* to be modified as requests are aborted), and then loops over each of them to
* perform the abortion. Doing so will trigger the ajaxComplete event against
* the document, which will remove the request from the pool-array.
*
* @access public
* @return void
*/
jQuery.xhrPool.abortAll = function() {
var requests = [];
for (var index in this) {
if (isFinite(index) === true) {
requests.push(this[index]);
}
}
for (index in requests) {
requests[index].abort();
}
};
/**
* jQuery.xhrPool.remove
*
* Loops over the requests, removes it once (and if) found, and then breaks out
* of the loop (since nothing else to do).
*
* @access public
* @param Object jqXHR
* @return void
*/
jQuery.xhrPool.remove = function(jqXHR) {
for (var index in this) {
if (this[index] === jqXHR) {
jQuery.xhrPool.splice(index, 1);
break;
}
}
};
/**
* Below events are attached to the document rather than defined the ajaxSetup
* to prevent possibly being overridden elsewhere (presumably by accident).
*/
$(document).ajaxSend(function(event, jqXHR, options) {
jQuery.xhrPool.push(jqXHR);
});
$(document).ajaxComplete(function(event, jqXHR, options) {
jQuery.xhrPool.remove(jqXHR);
});
สร้างกลุ่มคำขออาแจ็กซ์ทั้งหมดและยกเลิก .....
var xhrQueue = [];
$(document).ajaxSend(function(event,jqxhr,settings){
xhrQueue.push(jqxhr); //alert(settings.url);
});
$(document).ajaxComplete(function(event,jqxhr,settings){
var i;
if((i=$.inArray(jqxhr,xhrQueue)) > -1){
xhrQueue.splice(i,1); //alert("C:"+settings.url);
}
});
ajaxAbort = function (){ //alert("abortStart");
var i=0;
while(xhrQueue.length){
xhrQueue[i++] .abort(); //alert(i+":"+xhrQueue[i++]);
}
};
ดีกว่าที่จะใช้รหัสอิสระ .....
var xhrQueue = [];
$(document).ajaxSend(function(event,jqxhr,settings){
xhrQueue.push(jqxhr); //alert(settings.url);
});
$(document).ajaxComplete(function(event,jqxhr,settings){
var i;
if((i=$.inArray(jqxhr,xhrQueue)) > -1){
xhrQueue.splice(i,1); //alert("C:"+settings.url);
}
});
ajaxAbort = function (){ //alert("abortStart");
var i=0;
while(xhrQueue.length){
xhrQueue[i++] .abort(); //alert(i+":"+xhrQueue[i++]);
}
};
มีความสำคัญพอเพียง: บอกว่าคุณต้องการออกจากระบบและคุณกำลังสร้างคำขอใหม่ด้วยตัวจับเวลา: เนื่องจากข้อมูลเซสชันได้รับการต่ออายุด้วย bootstrap ใหม่แต่ละอัน (บางทีคุณอาจบอกได้ว่าฉันกำลังพูดถึง Drupal แต่นี่อาจเป็นเว็บไซต์ที่ใช้เซสชัน) ฉันต้องผ่านสคริปต์ทั้งหมดของฉันด้วยการค้นหาและแทนที่ทำให้ฉันมีสิ่งต่าง ๆ มากมายที่ทำงานในกรณีที่แตกต่างกัน: ตัวแปรทั่วโลกที่ด้านบน:
var ajReq = [];
var canAj = true;
function abort_all(){
for(x in ajReq){
ajReq[x].abort();
ajReq.splice(x, 1)
}
canAj = false;
}
function rmvReq(ranNum){
var temp = [];
var i = 0;
for(x in ajReq){
if(x == ranNum){
ajReq[x].abort();
ajReq.splice(x, 1);
}
i++;
}
}
function randReqIndx(){
if(!canAj){ return 0; }
return Math.random()*1000;
}
function getReqIndx(){
var ranNum;
if(ajReq.length){
while(!ranNum){
ranNum = randReqIndx();
for(x in ajReq){
if(x===ranNum){
ranNum = null;
}
}
}
return ranMum;
}
return randReqIndx();
}
$(document).ready(function(){
$("a").each(function(){
if($(this).attr('href').indexOf('/logout')!=-1){
$(this).click(function(){
abort_all();
});
}
})
});
// Then in all of my scripts I wrapped my ajax calls... If anyone has a suggestion for a
// global way to do this, please post
var reqIndx = getReqIndx();
if(reqIndx!=0){
ajReq[reqIndx] = $.post(ajax, { 'action': 'update_quantities', iids:iidstr, qtys:qtystr },
function(data){
//..do stuff
rmvReq(reqIndx);
},'json');
}
var Request = {
List: [],
AbortAll: function () {
var _self = this;
$.each(_self.List, (i, v) => {
v.abort();
});
}
}
var settings = {
"url": "http://localhost",
success: function (resp) {
console.log(resp)
}
}
Request.List.push($.ajax(settings));
เมื่อใดก็ตามที่คุณต้องการยกเลิกคำขอ ajax ทั้งหมดคุณเพียงแค่เรียกสายนี้
Request.AbortAll()
มีวิธีแก้ปัญหาหลอกตาฉันใช้เพื่อยกเลิกการร้องขอ ajax ทั้งหมด โซลูชันนี้โหลดซ้ำทั้งหน้า วิธีนี้เป็นวิธีที่ดีถ้าคุณไม่ต้องการกำหนด ID ให้กับคำขอ ajax แต่ละคำขอและถ้าคุณทำการร้องขอ ajax ภายใน for-loop นี่จะทำให้แน่ใจว่าคำขอ ajax ทั้งหมดถูกฆ่า
location.reload();
ต่อไปนี้เป็นวิธีการเชื่อมโยงสิ่งนี้เข้ากับการคลิกใด ๆ (มีประโยชน์หากหน้าของคุณกำลังโทร AJAX จำนวนมากและคุณพยายามนำทางไป)
$ ->
$.xhrPool = [];
$(document).ajaxSend (e, jqXHR, options) ->
$.xhrPool.push(jqXHR)
$(document).ajaxComplete (e, jqXHR, options) ->
$.xhrPool = $.grep($.xhrPool, (x) -> return x != jqXHR);
$(document).delegate 'a', 'click', ->
while (request = $.xhrPool.pop())
request.abort()