我正在尝试将jsonp与jQuery一起使用但是我的行为不一致。有时脚本有效,有时却没有;我真的不明白为什么。
这是Chrome可能显示的错误:
Uncaught TypeError: Property 'jQuery18208278296771459281_1362854738133' of object [object Object] is not a function
在以下示例中,我只是尝试检查应用程序是否在线。但是这种不一致的行为可能发生在其他类似的ajax调用上:
$.ajaxSetup({
error: function (req, status, ex) {},
success: function (data, status, req) {},
timeout: 2000,
crossDomain: true,
contentType: "application/json",
dataType:"jsonp",
url: "http://myUrl.com/ping.php?preventCache="+new Date()
});
return $.ajax();
服务器端PHP文件也很简单:
<?php
header("Content-Type: application/javascript; charset=UTF-8");
echo $_GET['callback'];
?> ({ "status": "online" })
答案 0 :(得分:15)
当您的JSONP调用超时时(根据您的timeout: 2000
行,这是两秒钟),您将收到此行为,但数据在超时发生后到达。
JSONP不使用普通的XmlHTTPRequest。要做JSONP,jQuery会在文档中插入一个脚本标记,并创建一个临时函数来处理脚本标记加载(函数名称是错误消息中的长随机字符串)。
当你的超时发生并且脚本还没有完成加载时,jQuery会丢弃临时函数。之后的某个时候,脚本标记完成加载,并尝试调用该函数 - 但为时已晚,该函数已被删除。因此错误。
通过延长超时可能会减少错误,但基本问题是您无法取消加载脚本标记。如果它没有出错,那么它总是有可能比你的超时花费更长的时间。据我所知,这方面没有简洁的解决方案。你可以告诉jQuery使用一个显式命名的函数作为JSONP回调而不是自己创建,但是你需要跟踪自己是否超时。你可以使用CORS,这是另一回事。
可能你最好的选择就是忍受它。
答案 1 :(得分:5)
你的问题不是那么清楚,当我尝试两次使用相同的回调函数名时,我遇到了同样的错误。在任何情况下,这都是应该在jquery中调用jsonp的方式:
var mycallback = 'c'+Math.floor((Math.random()*100000000)+1);
$.ajax({
type: 'GET',
url: URL,
async: true,
jsonpCallback: mycallback,
contentType: "application/json",
dataType: 'jsonp'
}).done(function(json){
console.log(json);
callback(json);
}).fail(function(f){
console.log("f");
console.log(f.status);
}).always(function(){
// console.log('complete');
});
答案 2 :(得分:2)
检查您的脚本是否连续多次发出相同的AJAX请求。
我有一个错误的事件处理程序同时触发了两个请求,这导致了同样的问题。
(我假设您调用$ .ajaxSetup一次):看起来您打算为ping调用应用缓存占用,但在$ .ajaxSetup中执行此操作可能会产生相反的效果,因为URL将为所有人修复后续请求。