如何关闭ajax请求,如何取消/中止jQuery AJAX请求?

如何取消/中止jQuery AJAX请求?

我有一个每5秒钟发出一次AJAX请求。 但问题是在AJAX请求之前,如果先前的请求没有完成,我将中止该请求并发出新请求。

我的代码是这样的,如何解决这个问题?

$(document).ready(

var fn = function(){

$.ajax({

url: 'ajax/progress.ftl',

success: function(data) {

//do something

}

});

};

var interval = setInterval(fn, 500);

);

user556673 asked 2019-03-03T00:29:16Z

8个解决方案

343 votes

jquery ajax方法返回XMLHttpRequest对象。 您可以使用此对象取消请求。

XMLHttpRequest有一个中止方法,它取消了请求,但如果请求已经发送到服务器,那么即使我们中止请求但服务器不会等待/处理响应,服务器也会处理请求。

xhr对象还包含readyState,其中包含请求的状态(UNSENT-0,OPENED-1,HEADERS_RECEIVED-2,LOADING-3和DONE-4)。 我们可以用它来检查先前的请求是否已完成。

$(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);

);

Arun P Johny answered 2019-03-03T00:29:39Z

5 votes

我知道这可能有点晚了,但我遇到类似的问题,调用abort方法并没有真正中止请求。 相反,浏览器仍在等待它从未使用过的响应。此代码解决了该问题。

try {

xhr.onreadystatechange = null;

xhr.abort();

} catch (e) {}

Lyon answered 2019-03-03T00:30:02Z

3 votes

你为什么要中止请求?

如果每个请求超过五秒钟,会发生什么?

如果随请求传递的参数未更改,则不应中止请求。例如: - 请求用于检索通知数据。在这种情况下,好的方法是在完成前一个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);

);

Habeeb Perwad answered 2019-03-03T00:30:39Z

1 votes

当您向服务器发出请求时,请先检查进度是否为空(或获取该数据)。 如果它正在获取数据,则中止先前的请求并启动新请求。

var progress = null

function fn () {

if (progress) {

progress.abort();

}

progress = $.ajax('ajax/progress.ftl', {

success: function(data) {

//do something

progress = null;

}

});

}

Taz answered 2019-03-03T00:31:03Z

0 votes

jQuery的:以此为出发点 - 作为灵感。我这样解决了:  (这不是一个完美的解决方案,它只是中止最后一个实例并且是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.

BananaAcid answered 2019-03-03T00:31:27Z

0 votes

您可以使用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]

zawhtut answered 2019-03-03T00:32:04Z

0 votes

创建一个调用API的函数。 在此函数中,我们定义请求keypress - 即使这是变量的定义,也会立即调用请求,但现在我们将请求定义为变量。 在调用请求之前,我们检查我们的变量是否定义为typeof(callApiRequest) != 'undefined'以及是否等待suggestCategoryRequest.state() == 'pending' - 如果两者都为真,我们.abort()将阻止成功回调运行的请求。

// We need to wrap the call in a function

callApi = function () {

//check if request is defined, and status pending

if (typeof(callApiRequest) != 'undefined'

&& suggestCategoryRequest.state() == 'pending') {

//abort request

callApiRequest.abort()

}

//define and make request

callApiRequest = $.get("https://example.com", function (data) {

data = JSON.parse(data); //optional (for JSON data format)

//success callback

});

}

您的服务器/ API可能不支持中止请求(如果API已执行某些代码,该怎么办?),但javascript回调不会触发。 例如,当您向用户提供输入建议(例如主题标签输入)时,这很有用。

您可以通过添加错误回调的定义来进一步扩展此功能 - 如果请求被中止,应该会发生什么。

此代码段的常见用例是在keypress事件中触发的文本输入。 您可以使用超时,以防止发送(某些)您必须取消的请求.abort()。

mate.gwozdz answered 2019-03-03T00:32:50Z

-7 votes

您还应检查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);

);

programmer answered 2019-03-03T00:33:15Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值