如何在 Ajax(Post) 请求期间抛出自定义 http 状态码

Posted

技术标签:

【中文标题】如何在 Ajax(Post) 请求期间抛出自定义 http 状态码【英文标题】:How throw custom http status code during Ajax(Post) request 【发布时间】:2012-01-10 10:06:18 【问题描述】:

我需要在AjaxRequestControllerCustomFilterAttribute 中抛出HttpException

当我在 Controller 中抛出 Exception 时出现 403 错误

[HttpPost]
[CustomAuthorize]
public ActionResult AjaxSelectBinding()

     // 403 Error code
     throw new HttpException((int)HttpStatusCode.Forbidden, "Forbidden");

在客户端脚本中,我总是得到结果代码 - 500

 $.ajax(
            type: 'POST',
            url: '/Groups/AjaxSelectBinding',
            success: function(data) 
            ,
            error: function (xhr, ajaxOptions, thrownError) 
                 // HERE I GET ALWAYS 500 ERROR CODE
            
        );

如何在我的FilterAttribute 中抛出HttpException 并在客户端页面中获取此代码。我尝试这样做,但我得到200 状态码:

public class CustomAuthorize : AuthorizeAttribute

    public override void OnAuthorization(AuthorizationContext filterContext)
    
        base.OnAuthorization(filterContext);

        SharedControllerBase ctrl = (SharedControllerBase)filterContext.Controller;

        if (!ctrl.User.Identity.IsAuthenticated &&
             filterContext.HttpContext.Request.IsAjaxRequest())
        
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
        
    

当我尝试在FilterAttribute 中抛出Exception 时,我再次得到500 状态代码

【问题讨论】:

【参考方案1】:

首先HttpStatusCode.Unauthorized = 401,而不是 403 状态码。这两个代码之间有一个重要的区别。

当您将状态代码设置为 401 时,会发生一些令人讨厌的事情:您会自动被 ASP.NET 表单身份验证模块重定向到登录页面 => 登录页面提供状态代码 = 200. Phil Haack 在following blog post 中解决了这个问题。

throw new HttpException((int)HttpStatusCode.Forbidden, "Forbidden"); 而言,在您的控制器操作中,您会抛出一个 HttpException 类型的异常,并且其 StatusCode 设置为 401,但除此之外,绝对没有任何东西可以捕获此异常并设置对应的响应状态码。因此异常会冒泡,并且由于您可能没有全局异常处理程序,因此服务器会将其转换为 500 错误页面。

这是一个global exception handler 的示例,您可能会发现它很有用。

【讨论】:

谢谢。我不想在HttpStatusCode.Unauthorized 错误时重定向,因为在这种情况下,在客户端我得到登录页面和 200(成功)结果。我想在错误 ajax 函数回调中翻译我的自定义代码,但 Web 服务器总是以 500 状态代码通知我。在控制器中我可以捕获 2 个异常(访问和内部错误),在客户端代码中我需要翻译它。

以上是关于如何在 Ajax(Post) 请求期间抛出自定义 http 状态码的主要内容,如果未能解决你的问题,请参考以下文章

如何从 JWT 身份验证过滤器中抛出自定义异常

Spring:如何让过滤器抛出自定义异常?

Laravel Ajax 请求使用 post 方法抛出 MethodNotAllowedException

jQuery .ajax() POST 请求抛出 405(不允许的方法)但 GET 不会

在 Django 中使用 AJAX POST 请求进行 CSRF 检查期间禁止 403

Cakephp 3.4 AJAX 请求抛出 403 禁止错误