C# CORS配置方法 C# ASP.NET Core如何配置跨域

来源:这里教程网 时间:2026-02-21 17:39:20 作者:

ASP.NET Core 6+ 默认不启用 CORS,必须显式注册和启用

很多开发者以为只要加个

AddCors
就能跨域,结果前端仍报
Blocked by CORS policy
。根本原因是:CORS 中间件必须在
UseRouting
之后、
UseEndpoints
(或
UseAuthorization
)之前调用,且策略必须被实际应用到端点上。

常见错误写法:
— 在

Program.cs
里只调用了
services.AddCors()
,但没调用
app.UseCors()

— 把
app.UseCors()
放在
app.UseAuthentication()
之后;
— 使用了命名策略(如
"MyPolicy"
),但在控制器上漏写了
[EnableCors("MyPolicy")]
或没在
MapControllers()
前统一启用。

正确顺序(Minimal Hosting Model,.NET 6+):

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowFrontend", policy =>
        policy.WithOrigins("https://localhost:5173")
              .AllowAnyMethod()
              .AllowAnyHeader()
              .WithExposedHeaders("X-Total-Count")); // 如需暴露分页头
});
builder.Services.AddControllers();
var app = builder.Build();
app.UseRouting();
app.UseCors("AllowFrontend"); // ⚠️ 必须在这,且在 UseAuthentication/UseAuthorization 之前
app.UseAuthorization();
app.MapControllers();

UseCors() 位置错位会导致 OPTIONS 预检失败

CORS 预检请求(OPTIONS)由中间件拦截并响应。如果

UseCors()
挂载位置靠后,比如在
UseAuthorization()
之后,那么未认证的 OPTIONS 请求会被拒绝,返回 401,浏览器就直接报错,不会继续发真实请求。

典型现象:
— 浏览器 Network 面板看到 OPTIONS 请求状态是 401 或 403;
— 控制台报

Response to preflight request doesn't pass access control check

— 后端日志里看不到 OPTIONS 请求被处理的痕迹。

解决方案要点:

app.UseCors()
必须紧接在
app.UseRouting()
之后
不要在它前面放任何需要认证/授权的中间件(
UseAuthentication
UseAuthorization
UseHttpsRedirection
可以保留,但它们不拦截 OPTIONS)
若使用
RequireAuthorization()
装饰控制器或端点,确保 CORS 策略已启用——因为预检请求本身不带 token,不能被要求授权

开发环境用 WithOrigins("*") 是错的,会禁用 Cookie 和 Credentials

WithOrigins("*")
看似方便,但它与
AllowCredentials()
互斥。一旦你后续需要带 cookie 登录、或用
withCredentials: true
发请求,就必须指定明确的 origin,否则浏览器直接拒绝响应。

常见踩坑场景:

前端 Vue/React 项目跑在
https://localhost:5173
,后端却配了
WithOrigins("*")
,然后登录接口返回 200,但前端收不到 Set-Cookie
调试时临时加了
AllowCredentials()
,但没同步改
WithOrigins
,结果整个策略失效
测试环境和生产环境共用同一套策略,但生产域名有多个(如 www.a.com / a.com / app.a.com),只写一个会被拦截

安全建议:

开发阶段明确列出前端地址:

.WithOrigins("https://localhost:5173", "http://localhost:3000")

生产环境用配置驱动,例如读取
appsettings.json
中的
Cors:AllowedOrigins
数组,再循环添加。

Controller 级 [EnableCors] 和全局 UseCors 冲突时以更细粒度为准

如果你既在

Program.cs
调用了
app.UseCors("MyPolicy")
,又在某个控制器上写了
[EnableCors("OtherPolicy")]
,那么该控制器会使用
OtherPolicy
,其他控制器走
MyPolicy
。但如果控制器没加
[EnableCors]
,而你又没调用
app.UseCors()
,那它压根不受 CORS 管控——此时浏览器仍会拦截,因为没响应头。

容易忽略的细节:

[EnableCors]
是作用在类或方法上的特性,不是自动继承的;基类加了,子类不会自动生效
如果用了
app.UseCors()
但没传策略名(即
app.UseCors()
无参),它只会启用默认策略(
"_default"
),而你定义的命名策略不会被触发
Razor Pages 或
MapRazorPages()
的页面也需同样策略覆盖,不能只顾 API 控制器

最简健壮做法:开发期统一用

app.UseCors("AllowFrontend")
全局启用,控制器不额外加
[EnableCors]
;只有特殊接口(如公开的 webhook)才单独配宽松策略并显式标记。

相关推荐