[英]Abort Ajax requests using jQuery
是否有可能使用 jQuery取消/中止我尚未收到响应的 Ajax 请求?
Most of the jQuery Ajax methods return an XMLHttpRequest (or the equivalent) object, so you can just use abort()
.大多数 jQuery Ajax 方法都返回一个 XMLHttpRequest(或等效的)对象,因此您可以只使用
abort()
。
See the documentation:请参阅文档:
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()
UPDATE: As of jQuery 1.5 the returned object is a wrapper for the native XMLHttpRequest object called jqXHR.更新:从 jQuery 1.5 开始,返回的对象是名为 jqXHR 的原生 XMLHttpRequest 对象的包装器。 This object appears to expose all of the native properties and methods so the above example still works.
该对象似乎公开了所有本机属性和方法,因此上面的示例仍然有效。 See The jqXHR Object (jQuery API documentation).
请参阅jqXHR 对象(jQuery API 文档)。
UPDATE 2: As of jQuery 3, the ajax method now returns a promise with extra methods (like abort), so the above code still works, though the object being returned is not an xhr
any more.更新 2:从 jQuery 3 开始,ajax 方法现在返回一个带有额外方法(如 abort)的承诺,因此上面的代码仍然有效,尽管返回的对象不再是
xhr
。 See the 3.0 blog here .请参阅此处的3.0 博客。
UPDATE 3 : xhr.abort()
still works on jQuery 3.x.更新 3 :
xhr.abort()
仍然适用于 jQuery 3.x。 Don't assume the update 2 is correct.不要假设更新 2是正确的。 More info on jQuery Github repository .
有关 jQuery Github 存储库的更多信息。
You can't recall the request but you can set a timeout value after which the response will be ignored.您无法撤回请求,但您可以设置超时值,超时后响应将被忽略。 See this page for jquery AJAX options.
有关 jquery AJAX 选项,请参阅此页面。 I believe that your error callback will be called if the timeout period is exceeded.
我相信如果超过超时时间,您的错误回调将被调用。 There is already a default timeout on every AJAX request.
每个 AJAX 请求已经有一个默认超时。
You can also use theabort() method on the request object but, while it will cause the client to stop listening for the event, it
may
probably will not stop the server from processing it.您还可以在请求对象上使用abort()方法,但是,虽然它会导致客户端停止侦听事件,但它
可能
不会阻止服务器处理它。
It's an asynchronous
request, meaning once it's sent it's out there.这是一个
asynchronous
请求,这意味着一旦它被发送出去。
In case your server is starting a very expensive operation due to the AJAX
request, the best you can do is open your server to listen for cancel requests, and send a separate AJAX
request notifying the server to stop whatever it's doing.如果您的服务器由于
AJAX
请求而开始执行非常昂贵的操作,您能做的最好的事情就是打开服务器以侦听取消请求,然后发送一个单独的AJAX
请求,通知服务器停止正在执行的任何操作。
Otherwise, simply ignore the AJAX
response.否则,只需忽略
AJAX
响应。
Save the calls you make in an array, then call xhr.abort() on each.将您所做的调用保存在一个数组中,然后在每个调用上调用 xhr.abort()。
HUGE CAVEAT: You can abort a request, but that's only the client side.巨大的警告:您可以中止请求,但这只是客户端。 The server side could still be processing the request.
服务器端可能仍在处理请求。 If you are using something like PHP or ASP with session data, the session data is locked until the ajax has finished.
如果您使用 PHP 或 ASP 之类的东西来处理会话数据,则会话数据将被锁定,直到 ajax 完成。 So, to allow the user to continue browsing the website, you have to call session_write_close ().
所以,为了让用户继续浏览网站,你必须调用session_write_close ()。 This saves the session and unlocks it so that other pages waiting to continue will proceed.
这将保存会话并解锁它,以便其他等待继续的页面将继续进行。 Without this, several pages can be waiting for the lock to be removed.
如果没有这个,几个页面可能会等待锁定被删除。
AJAX requests may not complete in the order they were started. AJAX 请求可能不会按照它们开始的顺序完成。 Instead of aborting, you can choose to ignore all AJAX responses except for the most recent one:
除了中止之外,您可以选择忽略所有 AJAX 响应,而不是中止:
Rough outline of code:粗略的代码概要:
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
We just had to work around this problem and tested three different approaches.我们只需要解决这个问题并测试了三种不同的方法。
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" />
In our case we decided to use approach #3 as it produces less load for the server.在我们的例子中,我们决定使用方法 #3,因为它为服务器产生的负载更少。 But I am not 100% sure if jQuery guarantees the call of the .complete()-method, this could produce a deadlock situation.
但我不是 100% 确定 jQuery 是否保证 .complete() 方法的调用,这可能会产生死锁情况。 In our tests we could not reproduce such a situation.
在我们的测试中,我们无法重现这种情况。
It is always best practice to do something like this.做这样的事情总是最好的做法。
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);
});
But it is much better if you check an if statement to check whether the ajax request is null or not.但是如果你检查一个 if 语句来检查 ajax 请求是否为空,那就更好了。
meouw的解决方案是正确的,但是如果您对更多控制感兴趣,则可以尝试jQuery的Ajax Manager插件 。
Just call xhr.只需调用 xhr。 abort() whether it's jquery ajax object or native XMLHTTPRequest object.
abort()无论是 jquery ajax 对象还是原生 XMLHTTPRequest 对象。
example:例子:
//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);
As many people on the thread have noted, just because the request is aborted on the client-side, the server will still process the request.正如该线程中的许多人所指出的那样,仅仅因为请求在客户端中止,服务器仍将处理该请求。 This creates unnecessary load on the server because it's doing work that we've quit listening to on the front-end.
这会在服务器上造成不必要的负载,因为它正在执行我们已经停止在前端侦听的工作。
The problem I was trying to solve (that others may run in to as well) is that when the user entered information in an input field, I wanted to fire off a request for a Google Instant type of feel.我试图解决的问题(其他人也可能遇到)是,当用户在输入字段中输入信息时,我想触发对 Google Instant 类型感觉的请求。
To avoid firing unnecessary requests and to maintain the snappiness of the front-end, I did the following:为了避免触发不必要的请求并保持前端的敏捷性,我执行了以下操作:
var xhrQueue = [];
var xhrCount = 0;
$('#search_q').keyup(function(){
xhrQueue.push(xhrCount);
setTimeout(function(){
xhrCount = ++xhrCount;
if (xhrCount === xhrQueue.length) {
// Fire Your XHR //
}
}, 150);
});
This will essentially send one request every 150ms (a variable that you can customize for your own needs).这基本上每 150 毫秒发送一个请求(您可以根据自己的需要自定义一个变量)。 If you're having trouble understanding what exactly is happening here, log
xhrCount
and xhrQueue
to the console just before the if block.如果您无法理解此处究竟发生了什么,请在 if 块之前将
xhrCount
和xhrQueue
到控制台。
You can abort any continuous ajax call by using this您可以使用此中止任何连续的 ajax 调用
<input id="searchbox" name="searchbox" type="text" />
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
var request = null;
$('#searchbox').keyup(function () {
var id = $(this).val();
request = $.ajax({
type: "POST", //TODO: Must be changed to POST
url: "index.php",
data: {'id':id},
success: function () {
},
beforeSend: function () {
if (request !== null) {
request.abort();
}
}
});
});
</script>
I was doing a live search solution and needed to cancel pending requests that may have taken longer than the latest/most current request.我正在做一个实时搜索解决方案,需要取消可能比最新/最新请求花费的时间更长的待处理请求。
In my case I used something like this:在我的情况下,我使用了这样的东西:
//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
Just use ajax.abort() for example you could abort any pending ajax request before sending another one like this只需使用 ajax.abort() 例如,您可以在发送另一个这样的请求之前中止任何挂起的 ajax 请求
//check for existing ajax request
if(ajax){
ajax.abort();
}
//then you make another ajax request
$.ajax(
//your code here
);
there is no reliable way to do it, and I would not even try it, once the request is on the go;没有可靠的方法来做到这一点,一旦请求在路上,我什至不会尝试; the only way to react reasonably is to ignore the response.
做出合理反应的唯一方法是忽略响应。
in most cases, it may happen in situations like: a user clicks too often on a button triggering many consecutive XHR, here you have many options, either block the button till XHR is returned, or dont even trigger new XHR while another is running hinting the user to lean back - or discard any pending XHR response but the recent.在大多数情况下,它可能发生在以下情况:用户过于频繁地点击一个按钮触发了许多连续的 XHR,在这里你有很多选择,要么阻止按钮直到 XHR 返回,或者在另一个正在运行提示时甚至不触发新的 XHR用户向后靠 - 或丢弃任何未决的 XHR 响应,但最近的响应。
The following code shows initiating as well as aborting an Ajax request:以下代码显示了启动和中止 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();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="button" class="go" value="GO!" >
<input type="button" class="stop" value="STOP!" >
I had the problem of polling and once the page was closed the poll continued so in my cause a user would miss an update as a mysql value was being set for the next 50 seconds after page closing, even though I killed the ajax request, I figured away around, using $_SESSION to set a var won't update in the poll its self until its ended and a new one has started, so what I did was set a value in my database as 0 = offpage , while I'm polling I query that row and return false;我遇到了轮询问题,一旦页面关闭,轮询会继续进行,因此在我的原因中,用户会错过更新,因为在页面关闭后的接下来 50 秒内设置了 mysql 值,即使我杀死了 ajax 请求,我想通了,使用 $_SESSION 设置一个 var 不会在轮询中更新它自己直到它结束并且一个新的已经开始,所以我所做的是在我的数据库中设置一个值 0 = offpage ,而我轮询我查询该行并返回false; when it's 0 as querying in polling will get you current values obviously...
当它为 0 时,在轮询中查询显然会得到你当前的值......
I hope this helped我希望这有帮助
If xhr.abort();
如果
xhr.abort();
causes page reload,导致页面重新加载,
Then you can set onreadystatechange
before abort to prevent:然后您可以在中止之前设置
onreadystatechange
以防止:
// ↓ prevent page reload by abort()
xhr.onreadystatechange = null;
// ↓ may cause page reload
xhr.abort();
I have shared a demo that demonstrates how to cancel an AJAX request-- if data is not returned from the server within a predefined wait time.我分享了一个演示,它演示了如何取消 AJAX 请求——如果在预定义的等待时间内没有从服务器返回数据。
HTML : HTML :
<div id="info"></div>
JS CODE: JS代码:
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);
});
This is my implementation based on many answers above:这是我基于上述许多答案的实现:
var activeRequest = false; //global var
var filters = {...};
apply_filters(filters);
//function triggering the ajax request
function apply_filters(filters){
//prepare data and other functionalities
var data = {};
//limit the ajax calls
if (activeRequest === false){
activeRequest = true;
}else{
//abort if another ajax call is pending
$request.abort();
//just to be sure the ajax didn't complete before and activeRequest it's already false
activeRequest = true;
}
$request = $.ajax({
url : window.location.origin + '/your-url.php',
data: data,
type:'POST',
beforeSend: function(){
$('#ajax-loader-custom').show();
$('#blur-on-loading').addClass('blur');
},
success:function(data_filters){
data_filters = $.parseJSON(data_filters);
if( data_filters.posts ) {
$(document).find('#multiple-products ul.products li:last-child').after(data_filters.posts).fadeIn();
}
else{
return;
}
$('#ajax-loader-custom').fadeOut();
},
complete: function() {
activeRequest = false;
}
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.