使用jQuery,我怎么能 cancel/abort an Ajax request 我尚未收到响应?
18 回答
19
我正在做一个实时搜索解决方案,需要取消可能比最新/最新请求更长的待处理请求 .
就我而言,我使用了这样的东西:
//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
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
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);
});
8
做这样的事情总是最好的做法 .
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);
});
18 回答
我正在做一个实时搜索解决方案,需要取消可能比最新/最新请求更长的待处理请求 .
就我而言,我使用了这样的东西:
meouw's solution是正确的,但如果您对更多控制感兴趣,那么您可以尝试Ajax Manager plugin for jQuery .
我们只需要解决这个问题并测试三种不同的方法 .
确实取消了@meouw建议的请求
执行所有请求但仅处理上次提交的结果
只要另一个请求仍处于待处理状态,
就会阻止新请求
在我们的例子中,我们决定使用方法#3,因为它减少了服务器的负载 . 但我不是100%肯定,如果jQuery保证调用.complete() - 方法,这可能会产生死锁情况 . 在我们的测试中,我们无法重现这种情况 .
AJAX请求可能无法按启动顺序完成 . 您可以选择忽略除最新的AJAX响应之外的所有AJAX响应,而不是中止:
创建一个计数器
启动AJAX请求时递增计数器
使用计数器的当前值"stamp"请求
在成功回调中将标记与计数器进行比较以检查它是否是最近的请求
粗略的代码轮廓:
Demo on jsFiddle
没有可靠的方法可以做到这一点,一旦请求在旅途中,我甚至都不会尝试;合理反应的唯一方法是忽略响应 .
在大多数情况下,它可能发生在以下情况:用户经常点击触发多个连续XHR的按钮,这里有很多选项,要么阻止按钮直到返回XHR,要么甚至不触发新XHR而另一个正在运行提示用户倾斜 - 或丢弃任何未决的XHR响应,但最近 .
您可以使用此中止任何连续的ajax调用
我已经共享了一个demo,它演示了如何取消AJAX请求 - 如果在预定义的等待时间内没有从服务器返回数据 .
HTML :
JS CODE:
做这样的事情总是最好的做法 .
但是,如果检查if语句以检查ajax请求是否为null,则会好得多 .
只需拨打xhr . abort() 无论是jquery ajax对象还是原生XMLHTTPRequest对象 .
例:
以下代码显示了启动和中止Ajax请求:
只需使用ajax.abort(),例如你可以在发送另一个这样的ajax请求之前中止任何挂起的ajax请求
这是一个 asynchronous 请求,意味着一旦它出现了.155086_ .
如果您的服务器由于AJAX请求而开始非常昂贵的操作,您可以做的最好是打开您的服务器以侦听取消请求,并发送单独的AJAX请求,通知服务器停止它正在做的任何事情 .
否则,只需忽略AJAX响应 .
我有轮询的问题,一旦页面关闭,民意调查继续进行,所以在我的原因中,用户会错过更新,因为在页面关闭后的下一个50秒内设置了mysql值,即使我杀死了ajax请求,我想一想,使用$ _SESSION来设置var将不会在轮询中自动更新直到它结束并且一个新的已经开始,所以我所做的是在我的数据库中设置一个值为0 = offpage,而我是轮询我查询该行并返回false;当它为0时,在轮询中查询会明显地获得当前值...
我希望这有帮助
如果
xhr.abort();
导致页面重新加载,然后你可以在中止之前设置
onreadystatechange
以防止:您无法调用该请求,但可以设置超时值,之后将忽略响应 . 有关jquery AJAX选项,请参阅page . 我相信如果超过超时时间,将调用您的错误回调 . 每个AJAX请求都有一个默认超时 .
您也可以在请求对象上使用abort()方法,但是,虽然它会导致客户端停止侦听事件,但它可能不会阻止服务器处理它 .
由于线程上的许多人都注意到,仅仅因为请求在客户端中止,服务器仍将处理请求 . 这会在服务器上产生不必要的负载,因为它正在做我们已经退出前端监听的工作 .
我试图解决的问题(其他人可能会遇到的问题)是,当用户在输入字段中输入信息时,我想要发出Google Instant类型的请求 .
为避免发出不必要的请求并保持前端的快速性,我做了以下事情:
这基本上每次都会发送一个请求150ms(您可以根据自己的需要自定义的变量) . 如果您无法理解这里到底发生了什么,请在if块之前将
xhrCount
和xhrQueue
记录到控制台 .保存您在数组中进行的调用,然后在每个调用上调用xhr.abort() .
巨大的CAVEAT:您可以中止请求,但这只是客户端 . 服务器端仍然可以处理请求 . 如果您使用PHP或ASP等会话数据,会话数据将被锁定,直到ajax完成 . 因此,要允许用户继续浏览网站,您必须调用 session_write_close () . 这将保存会话并将其解锁,以便等待继续的其他页面继续进行 . 没有这个,几个页面可以等待删除锁 .
大多数jQuery Ajax方法返回XMLHttpRequest(或等效的)对象,因此您只需使用
abort()
.查看文档:
abort Method(MSDN) . 取消当前的HTTP请求 .
abort()(MDN) . 如果已经发送了请求,则此方法将中止请求 .
UPDATE: 从jQuery 1.5开始,返回的对象是名为jqXHR的本机XMLHttpRequest对象的包装器 . 此对象似乎显示所有本机属性和方法,因此上述示例仍然有效 . 请参阅The jqXHR Object(jQuery API文档) .
UPDATE 2: 从jQuery 3开始,ajax方法现在返回一个带有额外方法(如abort)的promise,所以上面的代码仍然有效,尽管返回的对象不再是
xhr
. 见3.0 blog here .UPDATE 3 :
xhr.abort()
仍适用于jQuery 3.x.不要认为更新2是正确的 . More info on jQuery Github repository .