16

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

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

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

有没有办法处理这个异常?

引发的异常是这样的(根据 Firebug): jQuery16102234208755205157_1308941669256 is not a function

而异常的内部结构是这样的: jQuery16102234208755205157_1308941669256({... my json data from a different domain....})

4

5 回答 5

11

基本答案就是这里给出的答案:您不能真正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

abort()当然,如果 jQuery 能为我们做到这一点,那就太好了。

于 2012-04-03T19:12:47.140 回答
2

不要中止请求

只需将jqXHR返回的对象存储在某处$.ajax()

theJqXHR = $.ajax(....

如果用户取消请求 null 保存的对象

// 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 请求。

  1. 在任何情况下,您都不会在服务器上节省资源,因为您发送的请求将被处理并且无法停止。并且会有回应。

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

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

于 2016-12-06T17:26:25.083 回答
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,
  ...
});
于 2012-06-14T13:49:25.363 回答
0

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)this._request

于 2014-06-16T19:43:00.253 回答
-3

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

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

 jqxhr.abort(); // should be what you're looking for
于 2011-06-24T19:04:36.353 回答