jQuery Ajax错误处理,显示自定义异常消息


726

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

例如,如果我想通过Struts by 在服务器端抛出异常throw new ApplicationException("User name already exists");,我想在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。

我不确定我要去哪里错。我该怎么做才能解决此问题?

Answers:


357

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

xhr.responseText

..在您的JavaScript中。


9
经过两年半的时间,这仍然是正确的方法... :)我走得更远,实际上返回了我自己的错误JSON对象,该对象可以处理单个或多个错误,对于服务器端表单验证非常有用。
AlexCode'7

@Wilson如此处其他高评价答案所示。
Sprintstar 2014年

3
现在是2014年。以JSON为主的时代。所以我用xhr.responseJSON。:D
拉维2014年

5
仅在确保已设置元类型的情况下(例如“ Content-type:application / json”),才设置xhr.responseJSON。我刚刚遇到了一个问题;已设置responseText-未设置responseJSON。
伊戈尔2014年

217

控制器:

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

13
这不是对该问题的“正确”答案,但是最肯定的是它显示了对该问题的更高层次的解决方案……很好!
瑞安·安德森

3
我在做类似的事情。如果一切都在开发盒中完成,它会很好地工作。如果我尝试从网络上的不同盒连接时,xhr.responseText包含了一般性的错误页面的HTML,而不是我的自定义信息,请参阅stackoverflow.com/questions/3882752/...
jamiebarrow

6
我相信您也应该添加response.StatusCode = 500; 行到OnException方法。
亚历山大·普罗科菲耶夫

4
我进行了修改-因为我想要500状态代码,但是要在状态描述中显示异常消息(而不是“内部服务器错误”),response.StatusCode = (int)HttpStatusCode.InternalServerError;并且response.StatusDescription = filterContext.Exception.Message;
-Kram

4
如果您使用的是IIS7或更高版本,则可能需要添加:response.TrySkipIisCustomErrors = true;
James Gaunt

97

服务器端:

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

81

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

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

5
+1',因为这是目前对该问题的唯一正确答案!您可以调用“ jsonValue.Message”以获取异常消息。
船长明智

2
实际上,它不是正确的答案,因为问题不询问有关JSON的问题,而示例请求专门询问HTML作为响应。
SingleShot

+1正确。注意,通常会通过jqXHR.responseText(字符串)发送JSON编码的对象。然后,您可以根据需要使用jsonValue对象。使用Firebug控制台通过console.log(jsonValue)查看响应。
jjwdesign 2013年

这给了我“未捕获的SyntaxError:意外号”
奔Racicot

1
可通过jqXHR对象的responseJSON属性使已解析的JSON对象可用。因此,无需解析responseText属性。您可以执行以下操作:console.log(jqXHR.responseJSON.Message)
Eric D'Souza

37

如果调用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) ); 
})

22

这就是我所做的,到目前为止,它在MVC 5应用程序中仍然有效。

控制器的返回类型为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;
    }
});

20

如果有人像2016年那样来这里回答问题,请使用自jQuery 3.0起已弃用的.fail()错误处理.error()

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

希望对您有所帮助


2
jqXHR.error()在jQuery 3.0中已弃用(实际上已删除),但据我所知,不赞成errorsuccess回调$.ajax()
尼尔·康威

16

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

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

  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
}

整个问题在此博客文章中详细介绍,您可以在其中找到在应用程序中运行该代码的所有代码。


14

我发现这很好,因为我可以解析我从服务器发送的消息,并向用户显示友好消息,而无需使用堆栈跟踪...

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

10

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

}


7

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

从以下位置更改JSON结构:

{welcome:"Welcome"}

至:

{"welcome":"Welcome"}

1
除非键是JS中的保留字,否则不要紧。我认为这不是这里的问题。
约翰·吉布

1
JSON.stringify({welcome:“ Welcome”})-> {“ welcome”:“ Welcome”}
Thulasiram 2012年

5

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

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

我之所以这样说,是因为我在ASP.NET中遇到了类似的问题,当时我抛出类似ArgumentException(“不知道该怎么做...”)之类的东西,但是错误处理程序没有触发。

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


5

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

5

您在xhr对象中具有抛出异常的JSON对象。只需使用

alert(xhr.responseJSON.Message);

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


4
$("#save").click(function(){
    $("#save").ajaxError(function(event,xhr,settings,error){
        $(this).html{'error: ' (xhr ?xhr.status : '')+ ' ' + (error ? error:'unknown') + 'page: '+settings.url);
    });
});

4

此函数基本上会生成唯一的随机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));
}

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

类型:函数(jqXHR jqXHR,字符串textStatus,字符串errorThrown)

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


3

使用以下命令在服务器上引发新异常:

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

2

自问这个问题以来已经有很多年了,但我一直找不到xhr.responseText我想要的答案。它以以下格式返回了我的字符串:

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

我绝对不想向用户展示。我正在寻找的东西如下所示:

alert(xhr.responseJSON.message);

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


1
$("#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({...

... ... });


0

首先,我们需要在web.config中设置<serviceDebug includeExceptionDetailInFaults =“ True” />:

<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

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.