使用 jQuery 中止 JSONP ajax 请求
我正在使用 JSONP ajax 调用来加载来自不同域的一些内容,并且如果用户在按钮上引起“鼠标悬停”,则所有这些内容都会被执行。
我可以捕获 $.ajax() 调用返回作为 xhr 对象,并在每次用户引起“鼠标悬停”时使用它来中止 ajax 请求。但是 JSONP 回调函数仍然被调用,这会导致错误,我认为这是因为 xhr.abort() 方法不会阻止调用回调函数。
我尝试使用 try{}catch(e){} 包围 $.ajax() 调用,但在调用 xhr.abort() 方法后,错误仍然存在。
有没有办法处理这个异常?
引发的异常是这样的(根据Firebug): jQuery16102234208755205157_1308941669256 不是一个函数
而异常的内部结构是这样的: jQuery16102234208755205157_1308941669256({...我来自不同域的json数据...})
I'm using a JSONP ajax call to load some content from a different domain, and all this stuff is executed if the user causes a "mouseover" on a button.
I can capture the $.ajax() call return as a xhr object, and use it to abort the ajax request each time the user causes a "mouseover". But the JSONP callback function still gets called, and this causes an error, and I think it is beacuse the xhr.abort() method does not prevent the callback function to be called.
I've tried surrounding the $.ajax() call with try{}catch(e){}, but after I call the xhr.abort() method, the error continues.
Is there a way to handle that exception?
The raised exception is like this (according to Firebug):
jQuery16102234208755205157_1308941669256 is not a function
And the exception's internal structure is like this:
jQuery16102234208755205157_1308941669256({... my json data from a different domain....})
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
基本答案就是这里给出的答案:你不能真正
abort()
a JSONP 调用。所以真正的问题是,如何避免多余的回调调用和您看到的错误?您不能在回调周围使用
try...catch
因为它是异步的;你必须从 jQuery 的末端捕获它,并且 jQuery 通常不处理回调抛出的异常。 (我在我的书中讨论了这个问题,异步 JavaScript。)你想要做什么相反,为每个 Ajax 调用使用唯一的标识符,并且在调用成功回调时,检查该标识符是否与您进行调用时的标识符相同。这是一个简单的实现:在这里,我利用了这样一个事实:传递给
$.ajax
的任何内容都会附加到在回调中用作this
的对象。当然,如果 jQuery 让
abort()
为我们做这件事,那就太好了。The basic answer is simply the one given here: You can't really
abort()
a JSONP call. So the real question is, how do you avoid both superfluous callback invocations and the error you're seeing?You can't use
try...catch
around the callback because it's asynchronous; you'd have to catch it from jQuery's end, and jQuery generally doesn't handle exceptions thrown from callbacks. (I discuss this in my book, Async JavaScript.) What you want to do instead is use a unique identifier for each Ajax call and, when the success callback is invoked, check whether that identifier is the same as it was when you made the call. Here's an easy implementation:Here I'm taking advantage of the fact that anything you pass to
$.ajax
is attached to the object that's used asthis
in the callback.It'd be nice if jQuery made
abort()
do this for us, of course.不要中止请求
只需将
$.ajax()
返回的 jqXHR 对象存储在某处如果用户取消请求 null 保存的对象
最后当您收到响应(
success
回调)时,回调会将响应的 jqXHR 对象与保存的对象进行比较。没有 jQuery 错误。
一般建议不要依赖
abort()
,即使对于常规的 ajax 请求也是如此。无论如何,您都不会在服务器上节省资源,因为您发送的请求将被处理,并且无法阻止它。并且会返回响应。
某些(较旧的)浏览器无法正确处理
abort()
。只需“缓存”jqXHR 对象并自行处理CANCEL 场景。
Do not abort the request
Just store somewhere the jqXHR object returned by
$.ajax()
If the user cancel the request null the saved object
Finally when you receive the response (
success
callback) the callback will compare the jqXHR object of the response with the saved object.No jQuery errors.
As a general advice don't rely upon
abort()
, even for regular ajax requests.In any case you won't save resource on the server bacause the request you sent will be processed and there is no way to stop it. And a response will come back.
Some (older) browsers handle
abort()
not properly.Just "cache" the jqXHR object and handle the CANCEL scenario yourself.
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
并稍后将请求数据设置为此回调的参数,因此您将:为了避免设置其他参数来请求 URL 并调用回调,请将此参数添加到 ajax 方法中:
jsonp:false
,所以它看起来像:jsonpString overrides the callback function name in a jsonp request. This value will be used instead of 'callback' in the 'callback=?' part of the query string in the URL.
So
{jsonp:'onJSONPLoad'}
would result in'onJSONPLoad=?'
passed to the server. As of jQuery 1.5, setting the jsonp option to false prevents jQuery from adding the?callback
string to the URL or attempting to use=?
for transformation. In this case, you should also explicitly set thejsonpCallback
setting. For example,{ jsonp: false, jsonpCallback: "callbackName" }
http://api.jquery.com/jQuery.ajax/
jQuery adds
?callback=jQuery17109492628197185695_1339420031913
and later sets the request data as parameter to this callback, so you will have:To avoid setting additional parameters to request a URL and calling callback, add this parameter to ajax method:
jsonp:false
, so it will be look like:Trevor Burnham 的答案非常好,但您不应该跟踪请求计数,而应该将请求与 XHR 参数进行比较,如下所示;
在上一个请求完成之前再次调用
doRequest
或调用_freeRequest
将会导致if (this._request != = xhr)
行变为 true,因为this._request
将被删除或完全另一个请求。Trevor Burnham's answer is pretty good, but instead of tracking a request count, you should just compare the request to the XHR parameter, like so;
Calling
doRequest
again or_freeRequest
once before the previous request has completed, will result in the "abortion" of said request by causing theif (this._request !== xhr)
line to become true, sincethis._request
will either be deleted or another request altogether.在 jQuery 1.5 中,所有 Ajax API 都有一个围绕本机 XHR 对象的包装器对象。看一下:
http://api.jquery.com/jQuery.ajax/#jqXHR< /a>
In jQuery 1.5 all the Ajax APIs have a wrapper object around the native XHR objects. Take a look at:
http://api.jquery.com/jQuery.ajax/#jqXHR