代码之家  ›  专栏  ›  技术社区  ›  Andy May

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

  •  75
  • Andy May  · 技术社区  · 16 年前

    在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");
    });
    

    感谢您的回复!

    10 回复  |  直到 9 年前
        1
  •  51
  •   Adam Bellaire    16 年前

    似乎JSONP请求不会返回成功的结果,也不会触发任何事件、成功或失败,而且无论好坏,这显然是由设计造成的。

    在搜索了他们的bug追踪器之后, a patch 这可能是使用超时回调的解决方案。见 bug report #3442 . 如果无法捕获错误,则至少可以在等待合理的成功时间后超时。

        2
  •  51
  •   Community datashaman    7 年前

    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!'); });
    
        3
  •  15
  •   Matt    12 年前

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

    正如注释中提到的drawrider,您也可以使用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>
    

    <脚本& GT; 标记是否添加到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秒后,如果您的标志仍未设置,则请求超时。

        4
  •  14
  •   Farhan Ahmad    11 年前

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

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

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

    希望这有帮助:)

        5
  •  3
  •   delitescere    14 年前

    如果与提供程序协作,则可以在出现错误时发送另一个查询字符串参数作为函数进行回调。

    ?回调=?误差=?

    这被称为jsonpe,但它根本不是一个诽谤标准。

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

    不过,对于通信错误没有帮助-jquery必须进行更新,以便在超时时也回调错误函数,如亚当·贝莱尔的回答中所示。

        6
  •  2
  •   alex    13 年前

    似乎现在可以工作了:

    jQuery(document).ajaxError(function(event, request, settings){
       alert("Error");
    });
    
        7
  •  1
  •   Alexander    12 年前

    我用这个捕捉一个JSON错误

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

    编辑: 或者,您也可以获得错误消息。这将让您知道错误到底是什么。在catch块中尝试以下语法

    alert("Error : " + err);
    
        8
  •  0
  •   Marcel    12 年前

    梅比这作品?

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

    我不知道什么时候状态进入“错误”模式。但我用404测试了它,结果

        9
  •  0
  •   ghost rider3    11 年前

    通过在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
  •  0
  •   Community datashaman    7 年前

    我也把这个答案贴在 stack overflow - 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数据的变量,以及作为数据处理函数的成功函数。

    但是,您可以在success函数中添加状态和xhr变量。状态变量包含以下字符串之一:“success”、“notmodified”、“error”、“timeout”或“parserror”,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");
        }         
    });
    

    这样就可以很容易地跟踪超时和错误,而无需实现一个定制的超时跟踪器,该跟踪器在请求完成后启动。

    希望这能帮助仍在寻找这个问题答案的人。