.NET Core 5 WebAPI/SignalR遭CORS拦截,.NET Framework 4.7.2前端无法调用
报错根因
- CORS源地址配置格式错误:
WithOrigins方法接收的源地址不允许末尾带斜杠,你配置的https://local.redacted.com/末尾多了/,和实际请求的源https://local.redacted.com匹配失败,导致CORS规则不生效。
- CORS源地址配置格式错误:
- CORS规则混用逻辑冲突:你同时在
AddCors中定义了命名策略AllowCCORSOrigin,又在UseCors中使用内联匿名配置,同时控制器上的[EnableCors]特性没有指定对应策略名,多套配置冲突导致规则未正确应用。
- CORS规则混用逻辑冲突:你同时在
- 端点未显式启用CORS:你配置的CORS规则默认未自动覆盖控制器和SignalR Hub端点,需要为两类端点单独绑定CORS策略。
- IIS Express拦截OPTIONS预检请求:本地IIS Express默认会把OPTIONS类型的预检请求直接拦截,不会转发到.NET Core的CORS中间件处理,导致预检请求缺少响应头。
解决方案
第一步:修正Startup类的CORS配置
统一使用命名策略,修正源地址格式,调整端点配置,修改后的代码如下:
public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddCors(c => { c.AddPolicy( "AllowCCORSOrigin", options => options.WithOrigins("https://local.redacted.com") // 去掉末尾多余斜杠 .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }); services.AddControllers(); services.AddSingleton<KillChecker>(); services.AddHttpContextAccessor(); // 合并重复的SignalR注册配置 services.AddSignalR(o => { o.EnableDetailedErrors = true; }).AddMessagePackProtocol(); } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseFileServer(); app.UseStaticFiles(); app.UseRouting(); // 直接引用已定义的命名策略,不要重复写内联配置 app.UseCors("AllowCCORSOrigin"); app.UseEndpoints(endpoints => { endpoints.MapControllers().RequireCors("AllowCCORSOrigin"); // 控制器端点绑定CORS策略 endpoints.MapHub<KillHub>("/killhub").RequireCors("AllowCCORSOrigin"); // Hub端点绑定CORS策略 }); } }
第二步:修正控制器的CORS特性
明确指定要启用的策略名,如果全局已配置所有端点启用CORS,也可以直接移除控制器上的EnableCors特性:
[Route("[controller]"), EnableCors("AllowCCORSOrigin")] // 明确指定策略名 public class LaunchController : Controller
第三步:配置IIS Express放行OPTIONS请求
在.NET Core项目根目录新建/修改web.config文件,添加如下配置,避免IIS Express拦截预检请求:
<configuration> <system.webServer> <handlers> <remove name="aspNetCore" /> <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" /> </handlers> <httpProtocol> <customHeaders> <!-- 避免IIS重复添加CORS头导致冲突 --> <remove name="Access-Control-Allow-Origin" /> </customHeaders> </httpProtocol> </system.webServer> </configuration>
第四步:验证SignalR连接配置(可选)
如果后续对接SignalR,需要在JS连接配置中开启withCredentials属性:
const connection = new signalR.HubConnectionBuilder() .withUrl("https://localhost:60907/killhub", { withCredentials: true }) .build();
内容的提问来源于stack exchange,提问作者Rob C
相关产品推荐
相关产品推荐

