我正在用jQuery制作简单的自动提示(autocompleter)插件。不幸的是我必须使用jsonp。没关系,它可以工作,但是当我中止请求时,它会抛出错误。
Uncaught TypeError: Property 'jQuery171036404498340561986_1330693563756' of object [object Window] is not a function
有代码
if(xhr) {xhr.abort()};
xhr = $.ajax({
url: "someurl/getmedata",
type: 'get',
dataType: 'jsonp',
data: {q: "query"},
success: function(results) {},
error: function() {}
})
使用json,xml或其他请求的经典方式可以正常工作。
Anny暗示?
答案 0 :(得分:14)
JSONP
不使用XMLHTTPRequest
,但实际上在文档中创建了一个<script>
标记,以便能够发出跨域请求。
您根本无法中止JSONP请求。
$.ajax()文档中说明了这一点:
某些类型的Ajax请求,例如 JSONP 和跨域GET请求,不使用XHR ;在这些情况下,传递给回调的XMLHttpRequest和textStatus参数是未定义的。
至于jQuery 1.5+,以前是从$ .ajax()返回XHR对象,现在它返回一个超集jqXHR对象,它封装了XHR对象。
当传输机制不是XMLHttpRequest(例如,JSONP请求的脚本标记)时,jqXHR对象尽可能模拟本机XHR功能。
所以它返回一个对象但实际上没有一些功能,比如.abort()。
插件 jQuery-JSONP 似乎提供了手动中止JSONP请求的可能性。我自己没有用它,但值得一试。
答案 1 :(得分:4)
jQuery使用<script>
标记来实现JSONP。您无法中止脚本标记的加载。
答案 2 :(得分:0)
首先,使用一些排序逻辑。这将确保您的最后一个请求胜过旧的请求。 这里有example。
此外,您可以利用这些$.ajax
设置:
timeout:
为每个请求设置一个时间限制,并防止请求以静默方式失败。
beforeSend:
在拨打电话前验证了一些条件。补充测序助手。
As of jQuery 1.5, the beforeSend option will be called regardless of the type of request.
示例:
function updateResults() {
// Init counter & record current request
if (!window.reqSeq) window.reqSeq = 0;
window.reqSeq +=1;
var thisRequest = window.reqSeq;
$.ajax({
url: [..],
crossDomain: true,
contentType: "application/json",
dataType: 'jsonp',
timeout: 5000, // give 5 seconds of margin
data: { [..] },
beforeSend: function() {
if(thisRequest < window.reqSeq) {
return false;
}
},
success: function(data, textStatus, jqXHR) {
if(thisRequest < window.reqSeq) {
return;
}
else print(data);
},
error: function(jqXHR, textStatus, errorThrown) {
// it'll be called on timeout (error) and beforeSend (abort)
print(textStatus);
}
});
}