使用jQuery中止JSONP ajax请求

我正在使用JSONP ajax调用来加载来自不同域的一些内容,如果用户在按钮上导致“鼠标hover”,则执行所有这些操作。

我可以将$ .ajax()调用返回捕获为xhr对象,并在每次用户导致“鼠标hover”时使用它来中止ajax请求。 但是JSONP回调函数仍然被调用,这会导致错误,我认为这是因为xhr.abort()方法不会阻止调用回调函数。

我尝试使用try {} catch(e){}围绕$ .ajax()调用,但在调用xhr.abort()方法后,错误仍在继续。

有没有办法处理该exception?

引发的exception是这样的(根据Firebug): jQuery16102234208755205157_1308941669256不是函数

而exception的内部结构是这样的: jQuery16102234208755205157_1308941669256({…来自不同域的我的json数据….})

在jQuery 1.5中,所有Ajax API都有一个围绕本机XHR对象的包装器对象。 看一眼:

http://api.jquery.com/jQuery.ajax/#jqXHR

jqxhr.abort(); // should be what you're looking for 

基本答案就是这里给出的答案:你不能真正abort() JSONP调用。 所以真正的问题是,你如何避免多余的回调调用和你看到的错误?

你不能使用try...catch回调,因为它是异步的; 你必须从jQuery的结尾捕获它,而jQuery通常不处理从回调引发的exception。 (我在我的书中讨论了这个问题, Async JavaScript 。)你要做的是为每个Ajax调用使用唯一的标识符,并且在调用成功回调时,检查该标识符是否与创建时的标识符相同呼叫。 这是一个简单的实现:

 var requestCount = 0; $.ajax(url, { dataType: 'jsonp', requestCount: ++requestCount, success: function(response, code) { if (requestCount !== this.requestCount) return; // if we're still here, this is the latest request... } }); 

在这里,我充分利用了这样一个事实:传递给$.ajax任何内容都附加到回调中用作this对象的对象。

当然,如果jQuery让abort()为我们这样做,那就太好了。

jsonpString覆盖jsonp请求中的回调函数名称。 在’callback =?’中将使用此值代替’callback’ URL中查询字符串的一部分。

所以{jsonp:'onJSONPLoad'}会导致'onJSONPLoad=?' 传递给服务器。 从jQuery 1.5开始,将jsonp选项设置为false可防止jQuery将?callback字符串添加到URL或尝试使用=? 转型。 在这种情况下,您还应该显式设置jsonpCallback设置。 例如, { jsonp: false, jsonpCallback: "callbackName" }

http://api.jquery.com/jQuery.ajax/

jQuery添加?callback=jQuery17109492628197185695_1339420031913以及稍后将请求数据设置为此回调的参数,因此您将拥有:

 jQuery17109492628197185695_1339420031913({ "status": 200, "data": {your json} }) 

要避免设置其他参数来请求URL和调用回调,请将此参数添加到ajax方法: jsonp:false ,因此它将如下所示:

 $.ajax({ ... jsonp:false, ... }); 

不要中止请求

只需存储XHR对象的某个地方

 theXHR = $.ajax(.... 

如果用户取消请求,则保存已保存的对象

 // user canceled theXHR = null; 

最后,当您收到响应( success回调)时,回调将比较响应的XHR对象与保存的对象。

 function successCallback(data, textStatus, XHR ) { if( theXHR !== XHR ) { // user canceled; discard the response return; } // process the response } 

没有jQuery错误。


作为一般建议,不要依赖abort() ,即使是常规的ajax请求。

  1. 在任何情况下,您都不会在服务器上保存资源,因为您发送的请求将被处理,并且无法阻止它 。 响应将会回来。

  2. 一些(较旧的)浏览器不能正确处理abort()

只需“ 缓存 ”XHR对象并自己处理CANCEL场景。

Trevor Burnham的答案相当不错,但是您应该只是将请求与XHR参数进行比较,而不是跟踪请求计数;

 doRequest: function() { this._freeRequest(); this._request = $.getJSON(url + params + '&callback=?', function(response, status, xhr) { if (this._request !== xhr) return; // aborted // success }.bind(this)).done(this._freeRequest.bind(this)); } _freeRequest: function() { if (this._request) { delete this._request; } } 

在上一个请求完成之前再次调用doRequest_freeRequest ,将导致if (this._request !== xhr)行变为true,从而导致所述请求的“中止”,因为this._request将被删除或另一个请求。