我正在使用JSONP ajax调用来加载来自不同域的一些内容,如果用户在按钮上导致“鼠标悬停”,则执行所有这些操作。
我可以将$ .ajax()调用返回捕获为xhr对象,并在每次用户导致“鼠标悬停”时使用它来中止ajax请求。但是JSONP回调函数仍然被调用,这会导致错误,我认为这是因为xhr.abort()方法不会阻止调用回调函数。
我尝试使用try {} catch(e){}围绕$ .ajax()调用,但在调用xhr.abort()方法后,错误仍在继续。
有没有办法处理该异常?
引发的异常是这样的(根据Firebug): jQuery16102234208755205157_1308941669256不是功能
异常的内部结构如下: jQuery16102234208755205157_1308941669256({...来自其他域的我的json数据....})
答案 0 :(得分:11)
基本答案就是here给出的答案:你不能真正abort()
一个JSONP电话。所以真正的问题是,你如何避免多余的回调调用和你看到的错误?
你不能在回调周围使用try...catch
,因为它是异步的;你必须从jQuery的结尾捕获它,而jQuery通常不处理从回调引发的异常。 (我在我的书中讨论了这个问题,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()
为我们做这件事当然很好。
答案 1 :(得分:1)
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,
...
});
答案 2 :(得分:1)
请勿中止请求
只需存储$.ajax()
theJqXHR = $.ajax(....
如果用户取消请求,则保存已保存的对象
// user canceled
theJqXHR = null;
最后,当您收到响应(success
回调)时,回调会将响应的jqXHR对象与保存的对象进行比较。
function successCallback(data, textStatus, jqXHR )
{
if( theJqXHR !== jqXHR )
{
// user canceled; discard the response
return;
}
// process the response
}
没有jQuery错误。
一般建议不要依赖abort()
,即使是常规的ajax请求。
在任何情况下,您都不会在服务器上保存资源,因为您处理的请求将被处理,而且无法阻止。并会有回复。
某些(较旧的)浏览器无法正确处理abort()
。
只是" 缓存" jqXHR对象并自己处理 CANCEL 场景。
答案 3 :(得分:0)
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)
行变为真,所述请求的结果为真,因为this._request
将被删除或完全是另一个请求。
答案 4 :(得分:-3)
在jQuery 1.5中,所有Ajax API都有一个围绕本机XHR对象的包装器对象。看看:
http://api.jquery.com/jQuery.ajax/#jqXHR
jqxhr.abort(); // should be what you're looking for