Angular与ASP.NET Core项目跨域请求因authorization头缺失被拦截求助
看起来你遇到的是典型的CORS预检请求处理异常——虽然代码里配置了AllowAnyHeader,但浏览器还是提示authorization头未被允许。结合你的场景(Windows开发报错、Mac正常,Postman测试无问题),我整理了几个可能的原因和对应的解决方法:
1. 中间件顺序问题(最可能的核心原因)
在ASP.NET Core 2.x中,中间件的执行顺序直接决定请求的处理逻辑。你的UseCors虽然放在了UseMvc之前,但需要确保它在任何处理认证或业务请求的中间件之前执行。
看你的Configure方法,UseCors当前在UseStaticFiles之后、UseAuthentication之前,这个顺序理论上没问题,但可以尝试把它移到更早的位置(紧接异常处理中间件之后),避免其他中间件干扰CORS预检请求的处理:
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } // 将UseCors移到最靠前的位置(异常处理之后) app.UseCors(builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); }); app.UseStaticFiles(); app.UseSpaStaticFiles(); app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller}/{action=Index}/{id?}"); }); // ... 其他中间件保持不变 }
2. 显式配置CORS命名策略,替代临时构建
虽然直接在UseCors里构建策略是允许的,但显式配置命名策略能避免潜在的配置生效问题。修改你的ConfigureServices方法:
public void ConfigureServices(IServiceCollection services) { // ... 其他服务配置保持不变 services.AddCors(options => { options.AddPolicy("AllowAllRequests", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() // 如果你的请求需要携带Cookie,加上这一行 .AllowCredentials(); }); }); // ... 其他服务配置保持不变 }
然后在Configure方法中引用这个策略:
app.UseCors("AllowAllRequests");
3. Windows环境下的特殊干扰因素
浏览器缓存问题
CORS预检请求的结果会被浏览器缓存5分钟左右。如果之前你的后端没有允许Authorization头,浏览器可能还在使用旧的缓存结果。尝试用浏览器的隐私模式打开页面,或者手动清除缓存后再测试。
IIS Express配置冲突
Windows上你大概率用IIS Express运行项目,而IIS Express的web.config可能包含额外的HTTP头配置,覆盖了代码中的CORS设置。检查项目根目录下的web.config,如果有类似下面的配置,确保Access-Control-Allow-Headers包含authorization:
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Headers" value="Content-Type, Authorization" /> </customHeaders> </httpProtocol> </system.webServer>
如果有这个配置,要么删除它(让代码中的CORS配置生效),要么补充Authorization头。
4. 检查Angular HttpInterceptor的配置
确保你的拦截器没有给OPTIONS预检请求添加Authorization头——预检请求不需要携带认证信息,强行添加反而会导致失败。调整拦截器逻辑:
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // 跳过OPTIONS预检请求,直接放行 if (request.method === 'OPTIONS') { return next.handle(request); } // 给其他请求添加Authorization头 const authToken = localStorage.getItem('authToken'); const authReq = request.clone({ headers: request.headers.set('Authorization', `Bearer ${authToken}`) }); return next.handle(authReq); }
为什么Mac上正常?
Mac上你应该是直接用Kestrel运行项目,没有IIS Express的额外配置干扰,同时浏览器缓存的是正确的CORS响应,所以没有出现问题。
内容的提问来源于stack exchange,提问作者Lee

