如何显示 JSON 错误消息?

Posted

技术标签:

【中文标题】如何显示 JSON 错误消息?【英文标题】:How to display a JSON error message? 【发布时间】:2011-06-05 00:55:18 【问题描述】:

我目前正在开发一个 tumblr 主题并构建了一个使用 Tumblr API 执行以下操作的 jQuery JSON thingamabob:

用户会点击“帖子类型”链接(例如视频帖子),此时 jQuery 将使用 JSON 来抓取与该类型相关的所有帖子,然后在指定区域动态显示它们。

现在一切都很顺利,除了 Tumblr 是 Tumblr 并且他们的服务器不时受到敲门,Tumblr API 有时会离线。现在我无法预见该功能何时会关闭,这就是为什么如果 JSON(无论出于何种原因)无法加载帖子时,我想显示一些通用错误消息。

您会看到我已经编写了一些代码来在 jQuery 找不到与该帖子类型相关的任何帖子但它不涵盖任何服务器错误时显示错误消息。注意:我有时会收到此错误:

加载资源失败:服务器响应状态为 503(服务暂时不可用)

我需要为这个 503 错误消息编写一些代码,但我有点无能为力:)

这是 jQuery JSON 代码:

$('ul.right li').find('a').click(function() 
  var postType = this.className;
  var count = 0;
  byCategory(postType);
  return false;

  function byCategory(postType, callback) 
    $.getJSON('URL/api/read/json?type=' + postType + '&callback=?', function(data) 
    var article = [];
     $.each(data.posts, function(i, item) 
     // i = index
     // item = data for a particular post
     switch(item.type) 
     case 'photo':
     article[i] = '<div class="post_wrap"><div class="photo" style="padding-bottom:5px;">'
         + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/XSTldh6ds/photo_icon.png" /></a>'
         + '<a href="' + item.url + '" title="Title"><img src="' 
       + item['photo-url-500'] 
       + '" /></a></div></div>';
     count = 1;
     break;
     case 'video':
     article[i] = '<div class="post_wrap"><div class="video" style="padding-bottom:5px;">'
         + '<a href="' + item.url + '" title="Title" class="type_icon">'
       + '<img src="http://static.tumblr.com/ewjv7ap/nuSldhclv/video_icon.png" /></a>'
         + '<span style="margin: auto;">' 
       + item['video-player'] 
       + '</span>' 
       + '</div></div>';
     count = 1;
     break;
     case 'audio':
     if (use_IE == true) 
     article[i] = '<div class="post_wrap"><div class="regular">'
             + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/R50ldh5uj/audio_icon.png" /></a>'
         + '<h3><a href="'
         + item.url
       + '">'
       + item['id3-artist'] 
       +' - '
       + item['id3-title']
       + '</a></h3>'
       + '</div></div>';

     else 
     article[i] = '<div class="post_wrap"><div class="regular">'
             + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/R50ldh5uj/audio_icon.png" /></a>'
       + '<h3><a href="'
         + item.url
       + '">'
       + item['id3-artist'] 
       +' - '
       + item['id3-title']
       + '</a></h3><div class="player">'
       + item['audio-player'] 
       + '</div>'
       + '</div></div>';
    ;
     count = 1;
     break;
     case 'regular':
     article[i] = '<div class="post_wrap"><div class="regular">' 
       + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/dwxldhck1/regular_icon.png" /></a><h3><a href="'
       + item.url 
       + '">' 
       + item['regular-title']
       + '</a></h3><div class="description_container">'
       + item['regular-body'] 
       + '</div></div></div>';
     count = 1;
     break;
     case 'quote':
     article[i] = '<div class="post_wrap"><div class="quote">'
         + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/loEldhcpr/quote_icon.png" /></a><blockquote><h3><a href="' + item.url + '" title="Title">' 
       + item['quote-text']
       + '</a></h3></blockquote><cite>- '
       + item['quote-source'] 
       + '</cite></div></div>';
     count = 1;
     break;
     case 'conversation':
     article[i] = '<div class="post_wrap"><div class="chat">' 
       + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/MVuldhcth/conversation_icon.png" /></a><h3><a href="' 
       + item.url 
       + '">'
       + item['conversation-title']
       + '</a></h3></div></div>';
     count = 1;
     break;
     case 'link':
     article[i] = '<div class="post_wrap"><div class="link">' 
       + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/EQGldhc30/link_icon.png" /></a><h3><a href="'
       + item['link-url'] 
       + '" target="_blank">'
       + item['link-text']
       + '</a></h3></div></div>';
     count = 1;
     break;
     default:
     alert('No Entries Found.');
     ;
     ) // end each

     if (!(count == 0)) 
     $('#content_right')
      .hide('fast')
      .html('<div class="first_div"><span class="left_corner"></span><span class="right_corner"></span><h2>Displaying ' 
      + postType 
      + ' Posts Only</h2></div>'
      + article.join(''))
    .slideDown('fast')
     else 
     $('#content_right')
     .hide('fast')
     .html('<div class="first_div"><span class="left_corner"></span><span class="right_corner"></span><h2>Hmmm, currently there are no ' 
       + postType 
       + ' posts to display</h2></div>')
     .slideDown('fast')
    


    // end getJSON
   ); // end byCategory
  
 );

如果您想查看实际演示,请查看Elegantem,但请注意,根据 Tumblr 的性格,一切都可能对您完全正常(或不正常)。


更新 好的,所以在凌晨 2 点允许的情况下,按照 jmorts 的答案在下面尽可能接近字母后,我编写了以下代码但没有成功 - 没有弹出警报。 Myabe 我是个布偶,也许我只是个笨蛋,但如果你们这些绝地人能再偷看一眼,我真的很感激 :)
$('ul.right li').find('a').click(function() 
        var postType = this.className;
        var count = 0;
        byCategory(postType);
        return false;

        function byCategory(postType, callback) 
          $.getJSON('URL/api/read/json?type=' + postType + '&callback=?', function(data, textStatus, xhr)  // main callback function
          if(xhr.status == 500 || xhr.status == 404 || xhr.status == 503) 
                  yourErrorHandler(data, textStatus, xhr); // success
                 else 
                  yourCallbackToRunIfSuccessful(data);   // failed
                
              
        );


        function yourCallbackToRunIfSuccessful(data)   
          var article = [];
              $.each(data.posts, function(i, item) 
              // i = index
              // item = data for a particular post
              switch(item.type) 
              case 'photo':
              article[i] = '<div class="post_wrap"><div class="photo" style="padding-bottom:5px;">'
                            + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/XSTldh6ds/photo_icon.png" /></a>'
                            + '<a href="' + item.url + '" title="Title"><img src="' 
                            + item['photo-url-500'] 
                            + '" /></a></div></div>';
              count = 1;
              break;
              case 'video':
              article[i] = '<div class="post_wrap"><div class="video" style="padding-bottom:5px;">'
                            + '<a href="' + item.url + '" title="Title" class="type_icon">'
                            + '<img src="http://static.tumblr.com/ewjv7ap/nuSldhclv/video_icon.png" /></a>'
                            + '<span style="margin: auto;">' 
                            + item['video-player'] 
                            + '</span>' 
                            + '</div></div>';
              count = 1;
              break;
              case 'audio':
              if (use_IE == true) 
              article[i] = '<div class="post_wrap"><div class="regular">'
                            + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/R50ldh5uj/audio_icon.png" /></a>'
                            + '<h3><a href="'
                            + item.url
                            + '">'
                            + item['id3-artist'] 
                            +' - '
                            + item['id3-title']
                            + '</a></h3>'
                            + '</div></div>';

                 else 
              article[i] = '<div class="post_wrap"><div class="regular">'
                            + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/R50ldh5uj/audio_icon.png" /></a>'
                            + '<h3><a href="'
                            + item.url
                            + '">'
                            + item['id3-artist'] 
                            +' - '
                            + item['id3-title']
                            + '</a></h3><div class="player">'
                            + item['audio-player'] 
                            + '</div>'
                            + '</div></div>';
                ;
              count = 1;
              break;
              case 'regular':
              article[i] = '<div class="post_wrap"><div class="regular">' 
                            + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/dwxldhck1/regular_icon.png" /></a><h3><a href="'
                            + item.url 
                            + '">' 
                            + item['regular-title']
                            + '</a></h3><div class="description_container">'
                            + item['regular-body'] 
                            + '</div></div></div>';
              count = 1;
              break;
              case 'quote':
              article[i] = '<div class="post_wrap"><div class="quote">'
                            + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/loEldhcpr/quote_icon.png" /></a><blockquote><h3><a href="' + item.url + '" title="Title">' 
                            + item['quote-text']
                            + '</a></h3></blockquote><cite>- '
                            + item['quote-source'] 
                            + '</cite></div></div>';
              count = 1;
              break;
              case 'conversation':
              article[i] = '<div class="post_wrap"><div class="chat">' 
                            + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/MVuldhcth/conversation_icon.png" /></a><h3><a href="' 
                            + item.url 
                            + '">'
                            + item['conversation-title']
                            + '</a></h3></div></div>';
              count = 1;
              break;
              case 'link':
              article[i] = '<div class="post_wrap"><div class="link">' 
                            + '<a href="' + item.url + '" title="Title" class="type_icon"><img src="http://static.tumblr.com/ewjv7ap/EQGldhc30/link_icon.png" /></a><h3><a href="'
                            + item['link-url'] 
                            + '" target="_blank">'
                            + item['link-text']
                            + '</a></h3></div></div>';
              count = 1;
              break;
              default:
              alert('No Entries Found.');
              ;
              ) // end each

              if (!(count == 0)) 
              $('#content_right')
                .hide('fast')
                .html('<div class="first_div"><span class="left_corner"></span><span class="right_corner"></span><h2>Displaying ' 
                  + postType 
                  + ' Posts Only</h2></div>'
                  + article.join(''))
                .slideDown('fast')
                 else 
                    $('#content_right')
                    .hide('fast')
                    .html('<div class="first_div"><span class="left_corner"></span><span class="right_corner"></span><h2>Hmmm, currently there are no ' 
                      + postType 
                      + ' posts to display</h2></div>')
                    .slideDown('fast')
                


                // end getJSON
            ; // end byCategory

            function yourErrorHandler(data,textStatus,xhr) 
                alert("Server returned status code " + xhr.status + ".  Try again later.");
            
        
    );

【问题讨论】:

请注意,JSON 是 javascript 对象的表示法,而不是一种请求数据的方式。你可以改变你的问题来谈论 AJAX 而不是 JSON,因为 JSON 在这个问题中并不重要。 我认为您误解了 JSON 是什么。 JSON是一种数据表示格式;您可能指的是 XmlHttpRequest(出于某种原因通常称为“AJAX”)。 @Time Machine - 好点。 JSON 只是一种数据传输,类似于 XML。而 AJAX 是一种无需重新加载页面即可从服务器检索数据的技术,并且可以返回 XML、JSON、HTML、纯文本和可能其他格式的数据,尽管 AJAX 中的“X”代表“XML” . 有趣。三个 cmets 由不同的用户解释相同的内容,他们的名字中都包含字母 T。 @Time Machine - 大声笑,即使是问这个问题的人的名字中也有一个 T。去图吧。 【参考方案1】:

您的回调实际上采用了您未显示的其他 2 个参数:

     $.getJSON('URL/api/read/json?type=' + postType + 
          '&callback=?', 
              function(data, textStatus, xhr)    // main callback function
                if(xhr.status == 500 || xhr.status == 404 || xhr.status == 503) 
                  yourErrorHandler(data, textStatus, xhr); // success
                 else 
                  yourCallbackToRunIfSuccessful(data);   // failed
                
              
       );

       // your original code, but wrapped up in it's own function definition
       function yourCallbackToRunIfSuccessful(data) 
         var article = [];
         $.each(data.posts, function(i, item) 
         // i = index
         // item = data for a particular post
         switch(item.type) 
           case 'photo':
           ...
           ...
       

       function yourErrorHandler(data,textStatus,xhr) 
           alert("Server returned status code " + xhr.status + ".  Try again later.");
       

您可以使用 xhr 对象来检查原始 XMLHttpRequest 对象的状态。如果收到 404、503、500 等,则可以显示错误消息或运行备用函数。

http://api.jquery.com/jQuery.ajax

另外,如果您还没有用于 Firefox 的 Firebug,我强烈推荐它用于 JavaScript 调试:http://getfirebug.com/

更新:

getJSON JQuery AJAX 包装器没有错误回调处理程序。相反,您需要使用常规的 JQuery AJAX 处理程序来发出 JSON 请求:

  jQuery.ajax(
     type: "GET",
     url: 'URL/api/read/json?type=' + postType + 
          '&callback=?',
     dataType: "json",
     success: function(results)
         console.info("Success!");
         yourCallbackToRunIfSuccessful(results);
     ,
     error: function(XMLHttpRequest, textStatus, errorThrown)
         alert("Error");
         yourErrorHandler(XMLHttpRequest, textStatus, errorThrown);
     
  );

请务必注意,这不是 JSONP。这意味着您不能使用此功能进行跨域请求。

如果您使用我的原始答案来依赖 JSONP,那么您需要实施一个解决方案,您可以设置一个 setInterval 事件来轮询将在您的回调中更改的值。更多细节可以在这里找到:

http://groups.google.com/group/jquery-dev/browse_thread/thread/73ca6be8071479fb

【讨论】:

嗨,jmort,感谢您的快速回复——冒着听起来非常缺乏经验的风险,我不得不说我对 JSON 等的接触非常有限。您是否介意我要求一些代码,因为我以前从未使用过 XMLHttpRequests?哎呀,即使是一个或两个链接只是为了给我指出正确的方向也会很棒:) -- 在旁注中,非常感谢您抽出时间来解决我们的问题,非常感谢...... 其实你已经不远了。您应该在 &callback=?' 这一行之后获取匿名函数中的所有代码,并将其放入名为“yourCallbackToRunIfSuccessful”的函数中。然后用我的回调替换你的原始回调,检查 xhr.status 以查看响应代码是什么。我会再做一次澄清编辑。 嘿 jmort - 刚刚发布了一个更新:也许我是个布偶,或者只是错过了一些小事,但不知怎的,我的耳朵没有弹出警报。 Firebug、Chrome 调试器或任何其他 JavaScript 调试器中的错误代码是什么,它会向您显示 AJAX 调用返回的响应代码,该代码代表您收到错误时服务器上的状态?我假设为 500、503、404,但如果它不在您的列表中,您需要将其添加到 OR 条件列表中。 我还建议您在返回 false 后关闭该函数。由于您在那之后定义了其他函数,这可能会导致问题。

以上是关于如何显示 JSON 错误消息?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 API 向最终用户显示错误消息?

显示比“无法解码 JSON 对象”更好的错误消息

闪亮的不显示带有 HTML/JSON 错误消息的表格

Laravel - 当 API 路由错误或找不到时如何显示 JSON?

Swift 4 - 如何在 UIAlert 中显示来自 JSON Alamofire 的错误响应

返回任务的JSON错误消息 方法