使用 JSONP 时如何捕获 jQuery $.getJSON(或数据类型设置为“jsonp”的 $.ajax)错误?
Posted
技术标签:
【中文标题】使用 JSONP 时如何捕获 jQuery $.getJSON(或数据类型设置为“jsonp”的 $.ajax)错误?【英文标题】:How do I catch jQuery $.getJSON (or $.ajax with datatype set to 'jsonp') error when using JSONP? 【发布时间】:2010-09-23 12:32:48 【问题描述】:在 jQuery 中使用 JSONP 时是否可以捕获错误?我已经尝试了 $.getJSON 和 $.ajax 方法,但都不会捕获我正在测试的 404 错误。这是我尝试过的(请记住,这些都可以成功,但我想在失败时处理这种情况):
jQuery.ajax(
type: "GET",
url: handlerURL,
dataType: "jsonp",
success: function(results)
alert("Success!");
,
error: function(XMLHttpRequest, textStatus, errorThrown)
alert("Error");
);
还有:
jQuery.getJSON(handlerURL + "&callback=?",
function(jsonResult)
alert("Success!");
);
我也尝试过添加 $.ajaxError 但这也没有用:
jQuery(document).ajaxError(function(event, request, settings)
alert("Error");
);
提前感谢您的任何回复!
【问题讨论】:
使用 'error:function()' 有什么问题?? 它没有触发。 (记住这是 JSONP)。 【参考方案1】:Here 是我对类似问题的广泛回答。
代码如下:
jQuery.getJSON(handlerURL + "&callback=?",
function(jsonResult)
alert("Success!");
)
.done(function() alert('getJSON request succeeded!'); )
.fail(function(jqXHR, textStatus, errorThrown) alert('getJSON request failed! ' + textStatus); )
.always(function() alert('getJSON request ended!'); );
【讨论】:
我不明白为什么没有更多的赞成票。这显然是错误处理应该如何发生的。为什么接受的答案说“似乎不返回成功结果的 JSONP 请求永远不会触发任何事件、成功或失败”,而这显然不是真的?我不明白的事情。 仔细阅读后我认为它必须这样做,2008 年的事情在 jQuery 中有点不同;) @Daywalker 是的,从 JQuery 3.0 (api.jquery.com/jQuery.get) 开始,success/error/complete 方法已被弃用和删除【参考方案2】:似乎不返回成功结果的 JSONP 请求永远不会触发任何事件、成功或失败,无论好坏,这显然是设计使然。
在搜索他们的错误跟踪器后,a patch 可能是使用超时回调的可能解决方案。见bug report #3442。如果您无法捕获错误,您至少可以在等待一段合理的时间后超时。
【讨论】:
错误报告 #3442 链接已损坏。这可能是正确的链接:Ticket #3442 (closed enhancement: fixed) 同意!!!一个问题,即使我正在进行 JSONP 调用并收到 404 错误,但我没有收到 406 和 401 ???为什么 ??? ***.com/questions/18570486/… 错误答案,正确的是描述使用 .fail(function()) 的答案 这个答案不应该是正确的(现在?)***.com/a/19075701/2617354 是正确的方法。【参考方案3】:检测 JSONP 问题
如果您不想下载依赖项,您可以自己检测错误状态。这很容易。
您只能通过使用某种超时来检测 JSONP 错误。如果在特定时间内没有有效的响应,则假设一个错误。不过,错误基本上可以是任何东西。
这是检查错误的简单方法。只需使用success
标志:
var success = false;
$.getJSON(url, function(json)
success = true;
// ... whatever else your callback needs to do ...
);
// Set a 5-second (or however long you want) timeout to check for errors
setTimeout(function()
if (!success)
// Handle error accordingly
alert("Houston, we have a problem.");
, 5000);
正如 cmets 中提到的黎明骑士,你也可以使用 clearTimeout 代替:
var errorTimeout = setTimeout(function()
if (!success)
// Handle error accordingly
alert("Houston, we have a problem.");
, 5000);
$.getJSON(url, function(json)
clearTimeout(errorTimeout);
// ... whatever else your callback needs to do ...
);
为什么?继续阅读...
简而言之,JSONP 的工作原理如下:
JSONP 不像常规 AJAX 请求那样使用 XMLHttpRequest。相反,它将<script>
标记注入页面,其中“src”属性是请求的 URL。响应的内容被包装在一个 javascript 函数中,然后在下载时执行。
例如。
JSONP 请求:https://api.site.com/endpoint?this=that&callback=myFunc
Javascript 会将此脚本标签注入 DOM:
<script src="https://api.site.com/endpoint?this=that&callback=myFunc"></script>
将<script>
标签添加到DOM 时会发生什么?显然,它会被执行。
因此假设对该查询的响应产生如下 JSON 结果:
"answer":42
对于浏览器来说,这与脚本的源代码相同,因此它会被执行。但是当你执行这个时会发生什么:
<script>"answer":42</script>
嗯,没什么。它只是一个对象。它不会被存储、保存,也不会发生任何事情。
这就是 JSONP 请求将其结果包装在一个函数中的原因。必须支持 JSONP 序列化的服务器会看到您指定的 callback
参数,并改为返回:
myFunc("answer":42)
然后这会被执行:
<script>myFunc("answer":42)</script>
... 这更有用。在这种情况下,您的代码中的某处是一个名为 myFunc
的全局函数:
myFunc(data)
alert("The answer to life, the universe, and everything is: " + data.answer);
就是这样。这就是 JSONP 的“魔力”。然后构建超时检查非常简单,如上所示。发出请求,然后立即开始超时。 X 秒后,如果您的标志仍未设置,则请求超时。
【讨论】:
你也可以使用jsonpFailCheck = setTimeout(...)
,然后你可以使用success=true
而不是clearTimeout(jsonpFailCheck)
【参考方案4】:
我知道这个问题有点老了,但我没有看到一个可以简单解决问题的答案,所以我想我会分享我的“简单”解决方案。
$.getJSON("example.json", function()
console.log( "success" );
).fail(function()
console.log( "error" );
);
我们可以简单地使用.fail()
回调来检查是否发生了错误。
希望这会有所帮助:)
【讨论】:
请注意,这仅适用于版本 2.x(已放弃对 IE @LaurensRietveld 从 v1 开始支持:api.jquery.com/jQuery.getJSON【参考方案5】:如果您与提供者合作,您可以发送另一个查询字符串参数作为出现错误时回调的函数。
?callback=?&error=?
这被称为 JSONPE,但它根本不是事实上的标准。
然后提供程序将信息传递给错误函数以帮助您进行诊断。
但对通信错误没有帮助 - 必须更新 jQuery 以在超时时回调错误函数,如 Adam Bellaire 的回答。
【讨论】:
【参考方案6】:现在好像这样:
jQuery(document).ajaxError(function(event, request, settings)
alert("Error");
);
【讨论】:
仅适用于 jquery 2.x,不适用于 1.x【参考方案7】:我用它来捕获 JSON 错误
try
$.getJSON(ajaxURL,callback).ajaxError();
catch(err)
alert("wow");
alert("Error : "+ err);
编辑: 或者,您也可以收到错误消息。这会让你知道错误到底是什么。在 catch 块中尝试以下语法
alert("Error : " + err);
【讨论】:
如何对异步调用执行 try/catch?就 try/catch 而言,调用立即结束。回调或任何错误将在我们离开此代码的范围后很久之后发生。【参考方案8】:也许这行得通?
.complete(function(response, status)
if (response.status == "404")
alert("404 Error");
else
//Do something
if(status == "error")
alert("Error");
else
//Do something
);
我不知道状态何时进入“错误”模式。但我用 404 对其进行了测试,它响应了
【讨论】:
我们甚至可以检查错误函数的响应状态。更好的是我们可以利用误差函数。【参考方案9】:您可以通过在 ajax 请求中添加此属性来显式处理任何错误号:
statusCode:
404: function()
alert("page not found");
所以,你的代码应该是这样的:
jQuery.ajax(
type: "GET",
statusCode:
404: function()
alert("page not found");
,
url: handlerURL,
dataType: "jsonp",
success: function(results)
alert("Success!");
,
error: function(XMLHttpRequest, textStatus, errorThrown)
alert("Error");
);
希望这对你有帮助:)
【讨论】:
【参考方案10】:我也在stackoverflow - Error handling in getJSON calls发布了这个答案
我知道已经有一段时间没有人在这里回答了,发帖人可能已经从这里或其他地方得到了他的回答。然而,我确实认为这篇文章将帮助任何人在执行 getJSON 请求时寻找一种方法来跟踪错误和超时。因此,下面是我对问题的回答
getJSON 结构如下(见http://api.jqueri.com):
$(selector).getJSON(url,data,success(data,status,xhr))
大多数人使用
$.getJSON(url, datatosend, function(data)
//do something with the data
);
他们使用 url var 提供指向 JSON 数据的链接,datatosend 作为添加 "?callback=?"
和必须发送的其他变量以获取返回的正确 JSON 数据的位置,成功函数为处理数据的函数。
但是,您可以在成功函数中添加状态和 xhr 变量。 status 变量包含以下字符串之一:“success”、“notmodified”、“error”、“timeout”或“parsererror”,xhr 变量包含返回的 XMLHttpRequest 对象 (found on w3schools)
$.getJSON(url, datatosend, function(data, status, xhr)
if (status == "success")
//do something with the data
else if (status == "timeout")
alert("Something is wrong with the connection");
else if (status == "error" || status == "parsererror" )
alert("An error occured");
else
alert("datatosend did not change");
);
通过这种方式,可以轻松跟踪超时和错误,而无需实现在请求完成后启动的自定义超时跟踪器。
希望这对仍在寻找这个问题的答案的人有所帮助。
【讨论】:
对不起,这对 jQuery 2.2.3 没有任何影响。以上是关于使用 JSONP 时如何捕获 jQuery $.getJSON(或数据类型设置为“jsonp”的 $.ajax)错误?的主要内容,如果未能解决你的问题,请参考以下文章
jsonp 请求中的“未捕获的类型错误:无法读取未定义的属性‘toLowerCase’”
WCF 跨域使用 Jsonp 错误未捕获语法错误:意外令牌: