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

添加自定义异常中间件致.NET Core 3.1 CORS失效问题

问题分析与解决方案

你的CORS失效问题根源在于自定义异常中间件的逻辑错误,以及中间件顺序和异常处理时的CORS响应头缺失:

1. 自定义中间件的核心问题

原代码中你直接尝试获取IExceptionHandlerFeature,但这个特性只有框架自带的UseExceptionHandler中间件捕获异常后才会生成。你的自定义中间件只是检查当前是否已有异常,并没有捕获后续中间件抛出的异常,导致异常发生时无法正确处理,也不会携带CORS响应头。

2. 修正后的异常中间件代码

public class ExceptionMiddleware : IMiddleware
{
    private readonly ILogger<ExceptionMiddleware> _logger;
    private readonly IHostingEnvironment _env;
    private readonly ICorsPolicyProvider _corsPolicyProvider;

    public ExceptionMiddleware(ILogger<ExceptionMiddleware> logger, 
                               IHostingEnvironment env,
                               ICorsPolicyProvider corsPolicyProvider)
    {
        _logger = logger;
        _env = env;
        _corsPolicyProvider = corsPolicyProvider;
    }

    public async Task InvokeAsync(HttpContext context, RequestDelegate next)
    {
        try
        {
            // 执行后续中间件,捕获所有抛出的异常
            await next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "未处理的异常");

            // 应用CORS策略,确保跨域请求能获取响应头
            var corsPolicy = await _corsPolicyProvider.GetPolicyAsync(context, null);
            if (corsPolicy != null)
            {
                var evaluator = new CorsPolicyEvaluator();
                var corsResult = await evaluator.EvaluateAsync(context, corsPolicy);
                await corsResult.ApplyResultAsync(context, corsPolicy);
            }

            // 构建错误响应
            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
            context.Response.ContentType = "text/plain";
            var errorMessage = _env.IsDevelopment() 
                ? $"Error: {ex.Message}" 
                : "服务器发生意外错误";
            await context.Response.WriteAsync(errorMessage).ConfigureAwait(false);
        }
    }
}

3. 调整Startup.cs的中间件顺序

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        // 开发环境使用自带的异常页面,放在最前面
        app.UseDeveloperExceptionPage();
    }

    // 先启用CORS,确保异常处理时能应用CORS策略
    app.UseCors(x => x.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());

    // 再添加自定义异常中间件,捕获后续所有中间件的异常
    app.UseMiddleware<ExceptionMiddleware>();

    app.UseRequestTracking();

    app.UseAuthentication();
    app.UseAuthorization();

    app.UseMvc();
}

关键说明

  • 用try-catch包裹next(context),才能捕获后续中间件抛出的异常,这是自定义异常中间件的标准写法。
  • 异常处理时必须手动应用CORS策略(或直接添加Access-Control-Allow-Origin等响应头),否则浏览器会因为缺少跨域头拦截响应。
  • 中间件顺序:CORS必须在异常中间件之前配置,确保异常处理时能获取到已定义的CORS策略。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 20:27:46