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


76

结合使用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");
});

预先感谢您的任何答复!


使用'error:function(){}'怎么了?
詹姆斯,

1
它没有开火。(请记住,这是JSONP)。
安迪

Answers:


51

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

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


错误报告#3442链接已损坏。这可能是正确的链接:票证#3442(已关闭增强功能:固定)
hippietrail

同意!!!一个问题,即使我正在进行JSONP调用并得到404错误,但我却没有得到406和401?为什么??? stackoverflow.com/questions/18570486/…–
Hitesh

错误的答案,正确的答案是描述.fail(function())使用的答案
jumpjack

这个答案不应该是正确的答案(是吗?)stackoverflow.com/a/19075701/2617354是正确的方法。
Daywalker

53

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

这是代码:

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!'); });

11
我不明白为什么这还不支持。这显然是错误处理应该发生的方式。为什么接受的答案为什么说“似乎不返回成功结果的JSONP请求永远不会触发任何事件,成功或失败”,这显然是不正确的???我不明白的事情。
phil294

在仔细阅读之后,我认为这是必须要做的,在2008年jQuery中的事情有所不同;)
Daywalker

@Daywalker是的,自JQuery 3.0(api.jquery.com/jQuery.get)起,不赞成使用成功/错误/完成方法并将其删除
user2314737

16

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

就像注释中提到的thedawnrider一样,您也可以改用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秒钟后,如果您的标记仍未设置,则请求超时。


1
您也可以使用jsonpFailCheck = setTimeout(...),而不是success=true使用clearTimeout(jsonpFailCheck)
iancoleman 2012年

14

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

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

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

希望这可以帮助 :)


2
请注意,这仅适用于2.x版本(已不再支持IE <= 8),而不适用于1.x版本
Laurens Rietveld 2014年

@LaurensRietveld从v1开始受支持:api.jquery.com/jQuery.getJSON
Farhan Ahmad

3

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

?callback =?&error =?

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

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

但是,这对解决通讯错误没有帮助-jQuery必须进行更新以在超时时回调错误函数,如Adam Bellaire的回答。


2

好像现在正在工作:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});

仅适用于jquery 2.x,不适用于1.x
Laurens Rietveld 2014年

1

我用它来捕获JSON错误

try {
   $.getJSON(ajaxURL,callback).ajaxError();
} catch(err) {
   alert("wow");
   alert("Error : "+ err);
}

编辑:或者,您也可以获取错误消息。这将使您知道错误的确切原因。尝试在catch块中遵循以下语法

alert("Error : " + err);

3
如何进行异步调用的try / catch?就try / catch而言,呼叫立即结束。回调或任何错误会在我们离开此代码的范围很久之后发生。
Gone Coding

0

也许这行得通吗?

.complete(function(response, status) {
    if (response.status == "404")
        alert("404 Error");
    else{
        //Do something
    }   
    if(status == "error")
        alert("Error");
    else{
        //Do something
    }
});

我不知道状态何时进入“错误”模式。但是我用404测试了它


即使我们可以检查错误功能的响应状态。更好的是,我们可以利用误差函数。
iamjustcoder

0

您可以通过在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");
}
});

希望这对您有帮助:)


0

我也在堆栈溢出中发布了此答案-getJSON调用中的错误处理

我知道已经有一段时间了,因为有人在这里回答,而发帖人可能已经从这里或其他地方得到了他的答案。但是,我确实认为,这篇文章将对任何寻求在执行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数据的链接,而data则作为添加 "?callback=?"必须发送的变量和其他变量以获取正确的JSON数据的位置,并将成功函数用作处理数据的函数。

但是,您可以在成功函数中添加status和xhr变量。状态变量包含以下字符串之一:“成功”,“未修改”,“错误”,“超时”或“ parsererror”,而xhr变量包含返回的XMLHttpRequest对象(在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不会产生任何效果。
PhilPhil
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.