You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core MVC中DataTable Ajax请求401时如何跳转登录页

问题分析

你的核心问题在于:Ajax请求不会自动触发浏览器重定向,哪怕后端返回3xx状态码。当会话过期时,后端返回401未授权,但DataTables的Ajax请求只会接收响应内容,不会主动跳转页面;同时你的自定义中间件仅处理了「已认证但需强制登出」的场景,未覆盖「未认证(会话过期)」的Ajax请求分支。


解决方案

需要从后端中间件逻辑扩展和前端Ajax错误处理两方面入手,让Ajax请求在遇到未授权时能触发页面跳转。

1. 扩展自定义中间件逻辑

修改中间件,增加对「未认证Ajax请求」的判断,返回包含重定向地址的JSON响应(而非直接返回3xx重定向),同时保留对非Ajax请求的重定向处理:

public class CheckForceLogoutMiddleware
{
    private readonly RequestDelegate _next;

    public CheckForceLogoutMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context, UserManager<AppUser> userManager, SignInManager<AppUser> signInManager)
    {
        if (context.User.Identity.IsAuthenticated)
        {
            var user = await userManager.GetUserAsync(context.User);

            if (user?.ForceLogout == true)
            {
                await signInManager.SignOutAsync();
                HandleUnauthorizedRequest(context, "/Login");
                return;
            }
        }
        else
        {
            // 处理会话过期的未认证请求
            HandleUnauthorizedRequest(context, "/Login");
            return;
        }

        await _next(context);
    }

    // 统一处理未授权请求,区分Ajax和非Ajax
    private void HandleUnauthorizedRequest(HttpContext context, string redirectUrl)
    {
        if (IsAjaxRequest(context.Request))
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            context.Response.ContentType = "application/json";
            _ = context.Response.WriteAsJsonAsync(new { redirectUrl });
        }
        else
        {
            context.Response.Redirect(redirectUrl);
        }
    }

    // 判断是否为Ajax请求(通过X-Requested-With头)
    private bool IsAjaxRequest(HttpRequest request)
    {
        return request.Headers.TryGetValue("X-Requested-With", out var headerValue) &&
               headerValue.Equals("XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
    }
}

2. 前端DataTables错误处理配置

在DataTables初始化时添加错误监听,捕获401响应后解析JSON中的重定向地址,主动跳转页面:

$(document).ready(function() {
    // 禁用DataTables默认错误提示,改用自定义处理
    $.fn.dataTable.ext.errMode = 'none';

    // 监听DataTables的错误事件
    $('#yourDataTableId').on('error.dt', function(e, settings, techNote) {
        if (techNote.status === 401) {
            // 解析后端返回的JSON数据
            const response = techNote.responseJSON || JSON.parse(techNote.responseText);
            // 跳转到登录页
            window.location.href = response.redirectUrl;
        }
    });

    // 初始化DataTables
    $('#yourDataTableId').DataTable({
        serverSide: true,
        ajax: {
            url: '/YourDataApiEndpoint',
            type: 'POST'
        },
        // 其他列配置、分页等参数...
    });
});

补充优化(可选)

如果你的项目使用ASP.NET Core默认的Cookie认证,可以直接在认证配置中统一处理重定向逻辑,避免在自定义中间件中重复编写:

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.Events = new CookieAuthenticationEvents
        {
            OnRedirectToLogin = context =>
            {
                if (IsAjaxRequest(context.Request))
                {
                    context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                    context.Response.ContentType = "application/json";
                    return context.Response.WriteAsJsonAsync(new { redirectUrl = context.RedirectUri });
                }
                context.Response.Redirect(context.RedirectUri);
                return Task.CompletedTask;
            }
        };
    });

// 复用之前的IsAjaxRequest辅助方法
private bool IsAjaxRequest(HttpRequest request)
{
    return request.Headers.TryGetValue("X-Requested-With", out var headerValue) &&
           headerValue.Equals("XMLHttpRequest", StringComparison.OrdinalIgnoreCase);
}

内容的提问来源于stack exchange,提问作者TheSun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:12:40