循环调用带不同查询字符串的同一端点时出现CORS错误
问题场景
循环调用同一API端点(传递不同查询字符串)时,多数请求能正常返回预检/获取结果,但有1-2个请求触发CORS错误,检查发现响应缺失Origin/Methods/Credentials相关头。该问题仅出现在单个开发者环境中,相同场景在其他环境运行时所有请求均正常返回204(预检)/200(获取)。
客户端配置(Blazor WASM)
使用自定义HttpClient集成Azure AD身份验证,配置了CustomAuthorizationMessageHandler:
public CustomAuthorizationMessageHandler(IAccessTokenProvider provider, NavigationManager navigationManager) : base(provider, navigationManager) { ConfigureHandler( authorizedUrls: new[] { "https://localhost:44365" }); }
注册代码:
builder.Services.AddScoped<CustomAuthorizationMessageHandler>(); builder.Services.AddHttpClient<AuthorizedApiHttpClient>("API", client => { client.BaseAddress = new Uri(httpClientAddress); client.DefaultRequestHeaders.Add("Accept", "application/json"); }).AddHttpMessageHandler<CustomAuthorizationMessageHandler>();
API端CORS配置
API已配置宽松CORS策略,同时使用自定义CorsMiddleware:
builder.Services.AddCors() ... app.UseCors(x => x .SetIsOriginAllowed(origin => true) .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); app.UseCorsMiddleware();
自定义CorsMiddleware代码:
public class CorsMiddleware { private readonly RequestDelegate _next; public CorsMiddleware(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext httpContext) { httpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*"); httpContext.Response.Headers.Add("Access-Control-Allow-Credentials", "true"); httpContext.Response.Headers.Add("Access-Control-Allow-Headers", "*"); httpContext.Response.Headers.Add("Access-Control-Allow-Methods", "*"); return _next(httpContext); } } // Extension method used to add the middleware to the HTTP request pipeline. public static class CorsMiddlewareExtensions { public static IApplicationBuilder UseCorsMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<CorsMiddleware>(); } }
客户端Origin为https://localhost:44370/,目标API为https://localhost:44365/,Postman调用所有请求均正常,排除请求本身问题。
可能的原因分析
自定义中间件与官方CORS配置冲突
官方UseCors已经配置了完整的宽松策略,但自定义CorsMiddleware设置了Access-Control-Allow-Origin: *和AllowCredentials: true——这两个头互斥,浏览器会直接拒绝该配置。同时两个中间件叠加可能导致响应头重复或覆盖,部分请求的CORS头失效。建议直接移除自定义CorsMiddleware,官方配置已满足需求。单个开发者环境的浏览器干扰
- 浏览器缓存了旧的错误CORS响应头,可尝试强制刷新(Ctrl+Shift+R)或无痕模式测试;
- 隐私保护、广告拦截类扩展可能修改/移除CORS相关头,建议禁用所有扩展后重试。
并发请求触发的中间件执行问题
循环并发请求时,自定义中间件用Add方法添加响应头,若官方中间件已设置同名字段,会导致响应头出现多值(如多个Access-Control-Allow-Origin),浏览器判定为无效配置。另外,UseCorsMiddleware放在UseCors之后,执行顺序错误可能导致部分请求的CORS处理逻辑混乱。Azure AD令牌获取的异步延迟
CustomAuthorizationMessageHandler异步获取令牌,并发请求时部分请求可能在令牌获取完成前发送,导致请求缺失Authorization头,触发API端异常处理,跳过了CORS头的设置。可检查失败请求的请求头是否携带有效令牌,或在Handler中添加日志确认令牌获取状态。本地环境的端口/代理问题
该开发者本地可能存在端口冲突,或使用代理工具(如Fiddler)修改了请求Origin,导致API端CORS逻辑无法正确识别。建议重启开发服务器、检查代理状态后重试。
内容的提问来源于stack exchange,提问作者Robin

