如何在ASP.NET Core异常中间件中处理Ajax请求的日志与重定向?
解决ASP.NET Core MVC全局异常中间件在Ajax请求下的问题
你的问题核心在于:Ajax请求是异步HTTP请求,浏览器不会自动处理Redirect响应——因为Ajax请求的响应会被JavaScript代码接收,而非直接由浏览器解析执行跳转指令。要实现记录错误+跳转自定义错误页面的需求,需要区分请求类型分别处理:
解决方案:区分Ajax与非Ajax请求处理响应
修改你的异常中间件,先判断当前请求是否为Ajax请求,再分别返回对应响应:
- 判断Ajax请求:通过检查请求头
X-Requested-With是否等于XMLHttpRequest(这是大多数前端框架发起Ajax请求时会自动携带的标准头)。 - Ajax请求处理:返回JSON格式的错误信息(包含错误页URL),然后由前端JavaScript接收后执行页面跳转。
- 非Ajax请求处理:保持原有的
Redirect逻辑即可。
修改后的中间件代码
public class AppExceptionMiddleware: IMiddleware { public async Task InvokeAsync(HttpContext context, RequestDelegate next) { var _service = context.RequestServices.GetRequiredService<IUserAccountService>(); try { await next(context); } catch (Exception error) { // 统一记录错误到数据库 var routeData = context.GetRouteData(); var controllerName = routeData?.Values["controller"]?.ToString() ?? "Unknown"; var actionName = routeData?.Values["action"]?.ToString() ?? "Unknown"; var areaName = routeData?.Values["area"]?.ToString() ?? " "; _service.LogAppException(new Application.ViewModels.ErrorLogModel { errorMessage = error.Message, errorSource = error.Source, errorXML = error.ToString(), errorType = error.GetType().Name, controllerName = controllerName, actionName = actionName, areaName = areaName }); // 判断是否为Ajax请求 bool isAjaxRequest = context.Request.Headers["X-Requested-With"] == "XMLHttpRequest"; if (isAjaxRequest) { // 针对Ajax请求返回JSON响应,包含错误页URL context.Response.ContentType = "application/json"; context.Response.StatusCode = StatusCodes.Status200OK; // 也可根据需求使用500状态码 await context.Response.WriteAsJsonAsync(new { Success = false, ErrorMessage = "服务器发生异常,请稍后重试", RedirectUrl = "/error/oops" }); } else { // 非Ajax请求直接跳转错误页 context.Response.Redirect("/error/oops"); } } } }
前端配合处理(可选)
如果返回JSON格式响应,需要在前端Ajax请求的错误回调中处理跳转:
// 示例:jQuery Ajax请求 $.ajax({ url: "/your-api-endpoint", type: "POST", data: yourData, success: function(result) { // 正常处理逻辑 }, error: function(xhr) { var response = JSON.parse(xhr.responseText); if (response.RedirectUrl) { window.location.href = response.RedirectUrl; } } });
额外说明
- 若希望强制浏览器跳转(无需前端JS处理),也可给Ajax请求返回
302状态码并设置Location头,但部分前端框架可能会自动跟随重定向并返回重定向后的页面内容,而非触发浏览器跳转,因此返回JSON让前端主动跳转是更可靠的方案。 - 确保
/error/oops路由已正确映射到对应的错误页控制器和视图。
内容的提问来源于stack exchange,提问作者Mark Adesina Omoniyi
相关产品推荐
相关产品推荐

