【问题标题】:jQuery Ajax error handling, show custom exception messagesjQuery Ajax 错误处理,显示自定义异常消息
【发布时间】:2010-09-27 12:26:32
【问题描述】:

有什么方法可以在我的 jQuery AJAX 错误消息中显示自定义异常消息作为警报?

例如,如果我想通过throw new ApplicationException("User name already exists"); 在服务器端通过Struts 抛出异常,我想在jQuery AJAX 错误消息中捕获此消息('用户名已存在')。

jQuery("#save").click(function () {
  if (jQuery('#form').jVal()) {
    jQuery.ajax({
      type: "POST",
      url: "saveuser.do",
      dataType: "html",
      data: "userId=" + encodeURIComponent(trim(document.forms[0].userId.value)),
      success: function (response) {
        jQuery("#usergrid").trigger("reloadGrid");
        clear();
        alert("Details saved successfully!!!");
      },
      error: function (xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
      }
    });
  }
});

在第二个警报中,我警告抛出的错误,我收到 undefined 并且状态代码是 500。

我不确定我哪里出错了。我该怎么做才能解决这个问题?

【问题讨论】:

    标签: jquery ajax custom-exceptions


    【解决方案1】:

    确保将 Response.StatusCode 设置为 200 以外的值。使用 Response.Write 编写异常消息,然后使用...

    xhr.responseText
    

    ..在你的 javascript 中。

    【讨论】:

    • 这在 2 年半之后仍然是正确的方法...... :) 我走得更远了,实际上返回了我自己的错误 JSON 对象,它可以处理单个或多个错误,相当适用于服务器端表单验证。
    • @Wilson 就像这里的其他高评价答案所示。
    • 现在是 2014 年。JSON 主导的时代。所以我使用xhr.responseJSON。 :D
    • xhr.responseJSON 仅在您确保已设置元类型(例如“Content-type: application/json”)时才设置。这是我刚刚遇到的一个问题; responseText 已设置 - responseJSON 未设置。
    【解决方案2】:

    控制器:

    public class ClientErrorHandler : FilterAttribute, IExceptionFilter
    {
        public void OnException(ExceptionContext filterContext)
        {
            var response = filterContext.RequestContext.HttpContext.Response;
            response.Write(filterContext.Exception.Message);
            response.ContentType = MediaTypeNames.Text.Plain;
            filterContext.ExceptionHandled = true;
        }
    }
    
    [ClientErrorHandler]
    public class SomeController : Controller
    {
        [HttpPost]
        public ActionResult SomeAction()
        {
            throw new Exception("Error message");
        }
    }
    

    查看脚本:

    $.ajax({
        type: "post", url: "/SomeController/SomeAction",
        success: function (data, text) {
            //...
        },
        error: function (request, status, error) {
            alert(request.responseText);
        }
    });
    

    【讨论】:

    • 这不是问题的“正确”答案,但它肯定显示了对问题的更高级别的解决方案......很好!
    • 我正在做类似的事情。如果一切都在开发箱上完成,它工作正常。如果我尝试从网络上的其他框连接,xhr.responseText 包含通用错误页面 html 而不是我的自定义消息,请参阅stackoverflow.com/questions/3882752/…
    • 我相信您还应该在 OnException 方法中添加 response.StatusCode = 500; 行。
    • 我调整了这个 - 因为我想要 500 状态码,但在状态描述中包含异常消息(而不是“内部服务器错误”) - response.StatusCode = (int)HttpStatusCode.InternalServerError;response.StatusDescription = filterContext.Exception.Message;
    • 如果你使用的是IIS7或更高版本你可能需要添加:response.TrySkipIisCustomErrors = true;
    【解决方案3】:

    服务器端:

         doPost(HttpServletRequest request, HttpServletResponse response){ 
                try{ //logic
                }catch(ApplicationException exception){ 
                   response.setStatus(400);
                   response.getWriter().write(exception.getMessage());
                   //just added semicolon to end of line
    
               }
     }
    

    客户端:

     jQuery.ajax({// just showing error property
               error: function(jqXHR,error, errorThrown) {  
                   if(jqXHR.status&&jqXHR.status==400){
                        alert(jqXHR.responseText); 
                   }else{
                       alert("Something went wrong");
                   }
              }
        }); 
    

    通用 Ajax 错误处理

    如果我需要对所有 ajax 请求进行一些通用错误处理。我将设置 ajaxError 处理程序并在 html 内容顶部名为 errorcontainer 的 div 上显示错误。

    $("div#errorcontainer")
        .ajaxError(
            function(e, x, settings, exception) {
                var message;
                var statusErrorMap = {
                    '400' : "Server understood the request, but request content was invalid.",
                    '401' : "Unauthorized access.",
                    '403' : "Forbidden resource can't be accessed.",
                    '500' : "Internal server error.",
                    '503' : "Service unavailable."
                };
                if (x.status) {
                    message =statusErrorMap[x.status];
                                    if(!message){
                                          message="Unknown Error \n.";
                                      }
                }else if(exception=='parsererror'){
                    message="Error.\nParsing JSON Request failed.";
                }else if(exception=='timeout'){
                    message="Request Time out.";
                }else if(exception=='abort'){
                    message="Request was aborted by the server";
                }else {
                    message="Unknown Error \n.";
                }
                $(this).css("display","inline");
                $(this).html(message);
                     });
    

    【讨论】:

      【解决方案4】:

      您需要将responseText 转换为 JSON。使用 JQuery:

      jsonValue = jQuery.parseJSON( jqXHR.responseText );
      console.log(jsonValue.Message);
      

      【讨论】:

      • +1 '因为这是目前这个问题的唯一正确答案!您可以调用“jsonValue.Message”来获取异常消息。
      • 实际上它不是正确的答案,因为该问题没有询问 JSON 并且示例请求专门要求 HTML 作为响应。
      • +1 正确。注意,通过 jqXHR.responseText(字符串)发送 JSON 编码对象是很常见的。然后,您可以根据需要使用 jsonValue 对象。使用 Firebug 控制台查看使用 console.log(jsonValue) 的响应。
      • 这给了我 'Uncaught SyntaxError: Unexpected number'
      • 解析的 JSON 对象通过 jqXHR 对象的 responseJSON 属性可用。所以不需要解析 responseText 属性。你可以这样做:console.log(jqXHR.responseJSON.Message)
      【解决方案5】:

      如果调用asp.net,这将返回错误消息标题:

      formatErrorMessage 不是我自己写的,但我觉得它很有用。

      function formatErrorMessage(jqXHR, exception) {
      
          if (jqXHR.status === 0) {
              return ('Not connected.\nPlease verify your network connection.');
          } else if (jqXHR.status == 404) {
              return ('The requested page not found. [404]');
          } else if (jqXHR.status == 500) {
              return ('Internal Server Error [500].');
          } else if (exception === 'parsererror') {
              return ('Requested JSON parse failed.');
          } else if (exception === 'timeout') {
              return ('Time out error.');
          } else if (exception === 'abort') {
              return ('Ajax request aborted.');
          } else {
              return ('Uncaught Error.\n' + jqXHR.responseText);
          }
      }
      
      
      var jqxhr = $.post(addresshere, function() {
        alert("success");
      })
      .done(function() { alert("second success"); })
      .fail(function(xhr, err) { 
      
          var responseTitle= $(xhr.responseText).filter('title').get(0);
          alert($(responseTitle).text() + "\n" + formatErrorMessage(xhr, err) ); 
      })
      

      【讨论】:

        【解决方案6】:

        如果有人像 2016 年一样在这里寻求答案,请使用 .fail() 进行错误处理,因为自 jQuery 3.0 起,.error() 已被弃用

        $.ajax( "example.php" )
          .done(function() {
            alert( "success" );
          })
          .fail(function(jqXHR, textStatus, errorThrown) {
            //handle error here
          })
        

        希望对你有帮助

        【讨论】:

        • jqXHR.error() 在 jQuery 3.0 中已弃用(实际上已删除),但据我所知,$.ajax()errorsuccess 回调并未弃用。
        【解决方案7】:

        这就是我所做的,到目前为止它在 MVC 5 应用程序中工作。

        Controller 的返回类型是 ContentResult。

        public ContentResult DoSomething()
        {
            if(somethingIsTrue)
            {
                Response.StatusCode = 500 //Anything other than 2XX HTTP status codes should work
                Response.Write("My Message");
                return new ContentResult();
            }
        
            //Do something in here//
            string json = "whatever json goes here";
        
            return new ContentResult{Content = json, ContentType = "application/json"};
        }
        

        在客户端,这就是 ajax 函数的样子

        $.ajax({
            type: "POST",
            url: URL,
            data: DATA,
            dataType: "json",
            success: function (json) {
                //Do something with the returned json object.
            },
            error: function (xhr, status, errorThrown) {
                //Here the status code can be retrieved like;
                xhr.status;
        
                //The message added to Response object in Controller can be retrieved as following.
                xhr.responseText;
            }
        });
        

        【讨论】:

          【解决方案8】:

          通用/可重复使用的解决方案

          提供此答案以供所有遇到此问题的人将来参考。解决方案包括两件事:

          1. 自定义异常 ModelStateException 在服务器验证失败时抛出(当我们使用数据注释并使用强类型控制器操作参数时,模型状态会报告验证错误)
          2. 自定义控制器操作错误过滤器 HandleModelStateExceptionAttribute 捕获自定义异常并在正文中返回带有模型状态错误的 HTTP 错误状态

          这为 jQuery Ajax 调用提供了最佳的基础架构,以充分利用 successerror 处理程序的潜力。

          客户端代码

          $.ajax({
              type: "POST",
              url: "some/url",
              success: function(data, status, xhr) {
                  // handle success
              },
              error: function(xhr, status, error) {
                  // handle error
              }
          });
          

          服务器端代码

          [HandleModelStateException]
          public ActionResult Create(User user)
          {
              if (!this.ModelState.IsValid)
              {
                  throw new ModelStateException(this.ModelState);
              }
          
              // create new user because validation was successful
          }
          

          整个问题在this blog post 中有详细说明,您可以在其中找到在您的应用程序中运行它的所有代码。

          【讨论】:

            【解决方案9】:

             error:function (xhr, ajaxOptions, thrownError) {
                    alert(xhr.status);
                    alert(thrownError);
                  }
            在代码错误 ajax 请求中捕获错误连接客户端到服务器 如果您想显示应用程序的错误消息,请在成功范围内发送

            比如

            success: function(data){
               //   data is object  send  form server 
               //   property of data 
               //   status  type boolean 
               //   msg     type string
               //   result  type string
              if(data.status){ // true  not error 
                     $('#api_text').val(data.result);
              }
              else 
              {
                  $('#error_text').val(data.msg);
              }
            
            }

            【讨论】:

              【解决方案10】:

              我发现这很好,因为我可以解析出我从服务器发送的消息,并在没有堆栈跟踪的情况下向用户显示友好的消息...

              error: function (response) {
                    var r = jQuery.parseJSON(response.responseText);
                    alert("Message: " + r.Message);
                    alert("StackTrace: " + r.StackTrace);
                    alert("ExceptionType: " + r.ExceptionType);
              }
              

              【讨论】:

                【解决方案11】:

                这个函数基本上会生成唯一的随机 API 密钥,如果没有,则会出现带有错误消息的弹出对话框

                在查看页面中:

                <div class="form-group required">
                    <label class="col-sm-2 control-label" for="input-storename"><?php echo $entry_storename; ?></label>
                    <div class="col-sm-6">
                        <input type="text" class="apivalue"  id="api_text" readonly name="API" value="<?php echo strtoupper(substr(md5(rand().microtime()), 0, 12)); ?>" class="form-control" />                                                                    
                        <button type="button" class="changeKey1" value="Refresh">Re-Generate</button>
                    </div>
                </div>
                
                <script>
                $(document).ready(function(){
                    $('.changeKey1').click(function(){
                          debugger;
                        $.ajax({
                                url  :"index.php?route=account/apiaccess/regenerate",
                                type :'POST',
                                dataType: "json",
                                async:false,
                                contentType: "application/json; charset=utf-8",
                                success: function(data){
                                  var result =  data.sync_id.toUpperCase();
                                        if(result){
                                          $('#api_text').val(result);
                                        }
                                  debugger;
                                  },
                                error: function(xhr, ajaxOptions, thrownError) {
                                  alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
                                }
                
                        });
                    });
                  });
                </script>
                

                来自控制器:

                public function regenerate(){
                    $json = array();
                    $api_key = substr(md5(rand(0,100).microtime()), 0, 12);
                    $json['sync_id'] = $api_key; 
                    $json['message'] = 'Successfully API Generated';
                    $this->response->addHeader('Content-Type: application/json');
                    $this->response->setOutput(json_encode($json));
                }
                

                可选的回调参数指定在 load() 方法完成时运行的回调函数。回调函数可以有不同的参数:

                类型:函数(jqXHR jqXHR, String textStatus, String errorThrown)

                请求失败时调用的函数。 该函数接收三个参数:jqXHR(在 jQuery 1.4.x 中,XMLHttpRequest)对象、描述发生的错误类型的字符串和可选的异常对象(如果发生)。第二个参数的可能值(除了 null)是“timeout”、“error”、“abort”和“parsererror”。发生 HTTP 错误时,errorThrown 会接收 HTTP 状态的文本部分,例如“未找到”或“内部服务器错误”。从 jQuery 1.5 开始,错误设置可以接受一个函数数组。每个函数都会被依次调用。注意:跨域脚本和跨域 JSONP 请求不调用此处理程序。

                【讨论】:

                  【解决方案12】:

                  这可能是由于 JSON 字段名称没有引号引起的。

                  从以下位置更改 JSON 结构:

                  {welcome:"Welcome"}
                  

                  到:

                  {"welcome":"Welcome"}
                  

                  【讨论】:

                  • 这无关紧要,除非键是 JS 中的保留字。我不认为这是这里的问题。
                  • JSON.stringify({welcome:"Welcome"}) --> {"welcome":"Welcome"}
                  【解决方案13】:

                  您在 xhr 对象中有一个引发异常的 JSON 对象。只需使用

                  alert(xhr.responseJSON.Message);
                  

                  JSON 对象公开了另外两个属性:“ExceptionType”和“StackTrace”

                  【讨论】:

                    【解决方案14】:

                    我相信 Ajax 响应处理程序使用 HTTP 状态代码来检查是否有错误。

                    因此,如果您只是在服务器端代码上抛出 Java 异常,但 HTTP 响应没有 500 状态代码 jQuery(或者在这种情况下可能是 XMLHttpRequest 对象)将假设一切都很好。

                    我这么说是因为我在 ASP.NET 中遇到了类似的问题,我抛出了类似 ArgumentException("Don't know what to do...") 之类的东西,但错误处理程序没有触发。

                    然后我将 Response.StatusCode 设置为 500 或 200,无论我是否有错误。

                    【讨论】:

                      【解决方案15】:

                      jQuery.parseJSON 对成功和错误很有用。

                      $.ajax({
                          url: "controller/action",
                          type: 'POST',
                          success: function (data, textStatus, jqXHR) {
                              var obj = jQuery.parseJSON(jqXHR.responseText);
                              notify(data.toString());
                              notify(textStatus.toString());
                          },
                          error: function (data, textStatus, jqXHR) { notify(textStatus); }
                      });
                      

                      【讨论】:

                        【解决方案16】:
                        $("#save").click(function(){
                            $("#save").ajaxError(function(event,xhr,settings,error){
                                $(this).html{'error: ' (xhr ?xhr.status : '')+ ' ' + (error ? error:'unknown') + 'page: '+settings.url);
                            });
                        });
                        

                        【讨论】:

                          【解决方案17】:

                          在服务器上抛出一个新的异常:

                          Response.StatusCode = 500

                          Response.StatusDescription = ex.Message()

                          我相信StatusDescription返回给Ajax调用...

                          例子:

                                  Try
                          
                                      Dim file As String = Request.QueryString("file")
                          
                                      If String.IsNullOrEmpty(file) Then Throw New Exception("File does not exist")
                          
                                      Dim sTmpFolder As String = "Temp\" & Session.SessionID.ToString()
                          
                                      sTmpFolder = IO.Path.Combine(Request.PhysicalApplicationPath(), sTmpFolder)
                          
                                      file = IO.Path.Combine(sTmpFolder, file)
                          
                                      If IO.File.Exists(file) Then
                          
                                          IO.File.Delete(file)
                          
                                      End If
                          
                                  Catch ex As Exception
                          
                                      Response.StatusCode = 500
                          
                                      Response.StatusDescription = ex.Message()
                          
                                  End Try
                          

                          【讨论】:

                            【解决方案18】:

                            尽管问这个问题已经很多年了,但我仍然没有找到xhr.responseText 作为我正在寻找的答案。它以以下格式返回我的字符串:

                            "{"error":true,"message":"The user name or password is incorrect"}"
                            

                            我绝对不想向用户展示。我正在寻找的是如下内容:

                            alert(xhr.responseJSON.message);
                            

                            xhr.responseJSON.message 为我提供了来自 Json 对象的确切消息,可以显示给用户。

                            【讨论】:

                              【解决方案19】:
                              $("#fmlogin").submit(function(){
                                 $("#fmlogin").ajaxError(function(event,xhr,settings,error){
                                     $("#loading").fadeOut('fast');       
                                     $("#showdata").fadeIn('slow');   
                                     $("#showdata").html('Error please, try again later or reload the Page. Reason: ' + xhr.status);
                                     setTimeout(function() {$("#showdata").fadeOut({"opacity":"0"})} , 5500 + 1000); // delays 1 sec after the previous one
                                  });
                              });
                              

                              如果有任何表单是通过验证提交的

                              只需使用其余代码

                              $("#fmlogin").validate({...
                              

                              ... ... });

                              【讨论】:

                                【解决方案20】:

                                首先我们需要在web.config中设置

                                <serviceBehaviors> 
                                 <behavior name=""> 
                                  <serviceMetadata httpGetEnabled="true" /> 
                                    **<serviceDebug includeExceptionDetailInFaults="true" />** 
                                 </behavior> 
                                </serviceBehaviors>
                                

                                除了 jquery 级别的错误部分之外,您还需要解析包含异常的错误响应,例如:

                                .error(function (response, q, t) { 
                                  var r = jQuery.parseJSON(response.responseText); 
                                }); 
                                

                                然后使用 r.Message 你可以实际显示异常文本。

                                查看完整代码:http://www.codegateway.com/2012/04/jquery-ajax-handle-exception-thrown-by.html

                                【讨论】:

                                  【解决方案21】:

                                  就我而言,我刚刚从控制器中删除了 HTTP VERB。

                                      **//[HttpPost]**   ---- just removed this verb
                                      public JsonResult CascadeDpGetProduct(long categoryId)
                                      {
                                         
                                          List<ProductModel> list = new List<ProductModel>();
                                          list = dp.DpProductBasedOnCategoryandQty(categoryId);
                                          return Json(new SelectList(list, "Value", "Text", JsonRequestBehavior.AllowGet));
                                      }
                                  

                                  【讨论】:

                                    猜你喜欢
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2016-12-17
                                    • 2011-09-18
                                    • 2013-07-05
                                    • 2017-09-26
                                    • 1970-01-01
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多