如何取消/中止jQuery AJAX请求?
我有一个AJAX请求,将每5秒作出。 但是,如果前一个请求没有完成,问题出现在AJAX请求之前,我必须中止请求并发出新的请求。
我的代码是这样的,如何解决这个问题?
$(document).ready( var fn = function(){ $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something } }); }; var interval = setInterval(fn, 500); );
jquery ajax方法返回一个XMLHttpRequest对象。 您可以使用此对象来取消请求。
XMLHttpRequest有一个放弃方法,取消请求,但是如果请求已经发送到服务器,那么即使我们中止了请求,服务器也会处理请求,但是客户端不会等待/处理响应。
xhr对象还包含一个包含请求状态(UNSENT-0,OPENED-1,HEADERS_RECEIVED-2,LOADING-3和DONE-4)的readyState 。 我们可以用它来检查前一个请求是否完成。
$(document).ready( var xhr; var fn = function(){ if(xhr && xhr.readyState != 4){ xhr.abort(); } xhr = $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something } }); }; var interval = setInterval(fn, 500); );
只要使用ajax.abort()例如你可以放弃任何未决的Ajax请求,然后再发送这样的一个
//check for existing ajax request if(ajax){ ajax.abort(); } //then you make another ajax request $.ajax( //your code here );
我知道这可能有点晚,但我遇到类似的问题,在调用中止方法没有真正中止请求。 而浏览器仍然在等待一个从不使用的响应。 这段代码解决了这个问题。
try { xhr.onreadystatechange = null; xhr.abort(); } catch (e) {}
为什么要中止请求?
如果每个请求花费超过五秒钟,会发生什么?
如果传递请求的参数不变,则不应该中止请求。 例如: – 请求是为了检索通知数据。 在这种情况下,好的方法是在完成上一个Ajax请求之后才设置新的请求。
$(document).ready( var fn = function(){ $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something }, complete: function(){setTimeout(fn, 500);} }); }; var interval = setTimeout(fn, 500); );
当您向服务器发出请求时,请先检查进度是否为空(或取出该数据)。 如果正在提取数据,则放弃先前的请求并启动新的请求。
var progress = null function fn () { if (progress) { progress.abort(); } progress = $.ajax('ajax/progress.ftl',{ success: function(data) { //do something progress = null; } }); }
jQuery:以此为出发点 – 作为灵感。 我这样解决:(这不是一个完美的解决scheme,它只是中止最后一个实例,是WIP代码)
var singleAjax = function singleAjax_constructor(url, params) { // remember last jQuery's get request if (this.lastInstance) { this.lastInstance.abort(); // triggers .always() and .fail() this.lastInstance = false; } // how to use Deferred : http://api.jquery.com/category/deferred-object/ var $def = new $.Deferred(); // pass the deferrer's request handlers into the get response handlers this.lastInstance = $.get(url, params) .fail($def.reject) // triggers .always() and .fail() .success($def.resolve); // triggers .always() and .done() // return the deferrer's "control object", the promise object return $def.promise(); } // initiate first call singleAjax('/ajax.php', {a: 1, b: 2}) .always(function(a,b,c) {console && console.log(a,b,c);}); // second call kills first one singleAjax('/ajax.php', {a: 1, b: 2}) .always(function(a,b,c) {console && console.log(a,b,c);}); // here you might use .always() .fail() .success() etc.
你可以使用jquery-validate.js。 以下是jquery-validate.js的代码片段。
// ajax mode: abort // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() var pendingRequests = {}, ajax; // Use a prefilter if available (1.5+) if ( $.ajaxPrefilter ) { $.ajaxPrefilter(function( settings, _, xhr ) { var port = settings.port; if ( settings.mode === "abort" ) { if ( pendingRequests[port] ) { pendingRequests[port].abort(); } pendingRequests[port] = xhr; } }); } else { // Proxy ajax ajax = $.ajax; $.ajax = function( settings ) { var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, port = ( "port" in settings ? settings : $.ajaxSettings ).port; if ( mode === "abort" ) { if ( pendingRequests[port] ) { pendingRequests[port].abort(); } pendingRequests[port] = ajax.apply(this, arguments); return pendingRequests[port]; } return ajax.apply(this, arguments); }; }
所以,你只需要设置参数模式 中止当你正在做一个Ajax请求。
参考: https : //cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.js
jquery ajax方法返回一个XMLHttpRequest对象。 您可以使用此对象来取消请求。
$(document).ready( var xhr; var fun = function(){ if(xhr && xhr.readyState != 4){ xhr.abort(); } xhr = $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something code here } }); }; var interval = setInterval(fun, 1000); );
我希望这个答案对你有用。
你也应该检查readyState 0.因为当你使用xhr.abort()这个函数在这个对象中设置readyState为0,你的if检查将总是为true – readyState!= 4
$(document).ready( var xhr; var fn = function(){ if(xhr && xhr.readyState != 4 && xhr.readyState != 0){ xhr.abort(); } xhr = $.ajax({ url: 'ajax/progress.ftl', success: function(data) { //do something } }); }; var interval = setInterval(fn, 500); );