使用jQuery,如何取消/中止我尚未收到响应的Ajax请求?
大多数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开始,返回的对象是原生XMLHttpRequest对象的包装器,名为jqXHR.此对象似乎显示所有本机属性和方法,因此上述示例仍然有效.请参阅jqXHR对象(jQuery API文档).
更新2:
从jQuery 3开始,ajax方法现在返回一个带有额外方法(如abort)的promise,所以上面的代码仍然有效,尽管返回的对象不再存在xhr
.请参阅此处的3.0博客.
更新3:xhr.abort()
仍然适用于jQuery 3.x. 不要认为更新2是正确的.有关jQuery Github存储库的更多信息.
您无法调用该请求,但可以设置超时值,之后将忽略响应.有关jquery AJAX选项,请参阅此页面.我相信如果超过超时时间,将调用您的错误回调.每个AJAX请求都有一个默认超时.
您还可以在请求对象上使用abort()方法,但是,虽然它会导致客户端停止侦听事件,但它可能不会阻止服务器处理它.
这是一个异步请求,这意味着一旦它被发送到那里.
如果您的服务器由于AJAX请求而开始非常昂贵的操作,您可以做的最好是打开您的服务器以侦听取消请求,并发送单独的AJAX请求,通知服务器停止它正在做的任何事情.
否则,只需忽略AJAX响应.
保存您在数组中进行的调用,然后在每个调用上调用xhr.abort().
巨大的CAVEAT:您可以中止请求,但这只是客户端.服务器端仍然可以处理请求.如果您使用PHP或ASP等会话数据,会话数据将被锁定,直到ajax完成.因此,要允许用户继续浏览网站,您必须调用session_write_close().这将保存会话并解锁,以便其他页面等待继续.没有这个,几个页面可以等待删除锁.
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
我们只需要解决这个问题并测试三种不同的方法.
确实取消了@meouw建议的请求
执行所有请求但仅处理上次提交的结果
只要另一个请求仍处于待处理状态,就会阻止新请求
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();
});
})
做这样的事情总是最好的做法.
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(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);
我正在做一个实时搜索解决方案,需要取消可能比最新/最新请求更长的待处理请求.
就我而言,我使用了这样的东西:
//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
正如线程上的许多人所指出的那样,仅仅因为请求在客户端中止,服务器仍将处理请求.这会在服务器上产生不必要的负载,因为它正在做我们已经退出前端监听的工作.
我试图解决的问题(其他人可能会遇到的问题)是当用户在输入字段中输入信息时,我想要发出Google Instant类型的请求.
为避免触发不必要的请求并保持前端的快速性,我做了以下事情:
var xhrQueue = []; var xhrCount = 0; $('#search_q').keyup(function(){ xhrQueue.push(xhrCount); setTimeout(function(){ xhrCount = ++xhrCount; if (xhrCount === xhrQueue.length) { // Fire Your XHR // } }, 150); });
这实际上每150ms发送一个请求(一个可以根据自己的需要自定义的变量).如果您无法理解这里发生了什么,请在if块之前登录xhrCount
并xhrQueue
进入控制台.
只需使用ajax.abort(),例如你可以在发送另一个这样的ajax请求之前中止任何挂起的ajax请求
//check for existing ajax request if(ajax){ ajax.abort(); } //then you make another ajax request $.ajax( //your code here );
没有可靠的方法可以做到这一点,一旦请求在旅途中,我甚至都不会尝试; 合理反应的唯一方法是忽略响应.
在大多数情况下,它可能发生在以下情况:用户经常点击触发多个连续XHR的按钮,这里有很多选项,要么阻止按钮直到返回XHR,要么甚至不触发新XHR而另一个正在运行提示用户倾斜 - 或丢弃任何未决的XHR响应,但最近.
您可以使用此方法中止任何连续的ajax调用
以下代码显示了启动和中止Ajax请求:
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();
})
我有轮询的问题,一旦页面关闭,民意调查继续进行,所以在我的原因中,用户会错过更新,因为在页面关闭后的下一个50秒内设置了mysql值,即使我杀死了ajax请求,我想一想,使用$ _SESSION设置一个var将不会在轮询中自动更新直到它结束并且一个新的已经开始,所以我所做的是在我的数据库中设置一个值为0 = offpage,而我是轮询我查询该行并返回false; 当它为0时,在轮询中查询会明显地获得当前值...
我希望这有帮助