使用 JSONP 时,如何捕获 jQuery $.getJSON(或数据类型设置为“jsonp”的 $.ajax)错误?

IT技术 javascript jquery jsonp
2021-01-21 01:20:13

将 JSONP 与 jQuery 一起使用时是否可以捕获错误?我已经尝试了 $.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");
});

预先感谢您的任何答复!

6个回答

是我对类似问题的广泛回答。

这是代码:

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 请求永远不会触发任何事件、成功或失败”,而这显然不是真的???我不明白的事情。
2021-03-14 01:20:13
仔细阅读后,我认为必须这样做,即在 2008 年,jQuery 中的事情有些不同;)
2021-03-25 01:20:13
@Daywalker 是的,从 JQuery 3.0 ( api.jquery.com/jQuery.get ) 开始,成功/错误/完成方法已被弃用并删除
2021-03-25 01:20:13

似乎不返回成功结果的 JSONP 请求永远不会触发任何事件,成功或失败,无论好坏,这显然是设计使然。

在搜索他们的错误跟踪器后,有一个补丁可能是使用超时回调的可能解决方案。请参阅错误报告 #3442如果您无法捕获错误,您至少可以在等待一段合理的成功时间后超时。

同意!!!一个问题,即使我在进行 JSONP 调用并收到 404 错误,但我没有收到 406 和 401 ??? 为什么 ???stackoverflow.com/questions/18570486/...
2021-03-14 01:20:13
错误报告 #3442 链接已损坏。这可能是正确的链接:Ticket #3442(封闭增强:已修复)
2021-03-25 01:20:13
错误的答案,正确的答案是描述 .fail(function()) 的使用
2021-03-30 01:20:13
这个答案不应该是concideret正确的(不再是?)stackoverflow.com/a/19075701/2617354是正确的方法。
2021-03-31 01:20:13

检测 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);

正如 dawnrider 在评论中提到的,您也可以使用 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)
2021-04-05 01:20:13

我知道这个问题有点老了,但我没有看到一个可以简单解决问题的答案,所以我想我会分享我的“简单”解决方案。

$.getJSON("example.json", function() {
      console.log( "success" );
}).fail(function() { 
      console.log( "error" ); 
}); 

我们可以简单地使用.fail()回调来检查是否发生了错误。

希望这可以帮助 :)

请注意,这仅适用于 2.x 版(已放弃对 IE <= 8 的支持),而不适用于 1.x
2021-04-07 01:20:13
@LaurensRietveld 从 v1 开始就支持了:api.jquery.com/jQuery.getJSON
2021-04-12 01:20:13

如果您与提供者合作,您可以发送另一个查询字符串参数作为出现错误时回调的函数。

?回调=?&错误=?

这称为 JSONPE,但它根本不是事实上的标准。

然后提供程序将信息传递给错误函数以帮助您进行诊断。

虽然对通信错误没有帮助 - 必须更新 jQuery 才能在超时时回调错误函数,如 Adam Bellaire 的回答。