React + .NET 6项目CORS跨域求助:预检请求重定向被拦截
问题现状
在React + .NET 6项目中遭遇跨域报错,浏览器控制台提示:
Access to XMLHttpRequest at
'http://localhost:5144/api/schedule?station=DME&date=2023-08-22T09:26:55.437Z&range=60'
from origin 'http://localhost:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check:
Redirect is not allowed for a preflight request.
已尝试React代理配置、axios实例设置、.NET添加CORS策略等方案,均未解决,切换HTTPS环境问题依然存在。
核心原因分析
报错关键在于**"Redirect is not allowed for a preflight request"**,说明预检OPTIONS请求被服务器重定向,而非单纯的CORS策略未生效。常见触发场景:
- .NET端仅声明了CORS策略,但未在中间件管道中启用,同时请求路径与后端路由不匹配引发重定向
- React端代理配置与axios baseURL冲突,导致请求未走代理直接访问后端,触发跨域+重定向问题
- 后端API路由定义与请求路径不匹配,自动重定向过程中违反了预检请求的规则
分步解决方法
1. 修复.NET端CORS配置(核心步骤)
仅调用AddCors定义策略是不够的,必须在中间件管道中启用CORS,且严格控制中间件顺序:
修改Program.cs:
builder.Services.AddCors(p => p.AddPolicy("corsapp", builder => { // 开发环境明确指定前端地址,比通配符*更规范 builder.WithOrigins("http://localhost:3000") .AllowAnyMethod() .AllowAnyHeader(); })); // ...其他服务配置代码 var app = builder.Build(); // 启用CORS,必须放在UseRouting之后、UseAuthorization之前 app.UseCors("corsapp"); app.UseRouting(); app.UseAuthorization(); app.MapControllers(); app.Run();
2. 排查并解决后端重定向问题
检查API控制器的路由定义,若控制器路由为[Route("api/[controller]")],则正确请求路径应为/api/schedule(对应ScheduleController)。若存在重定向,可通过以下方式处理:
- 在控制器路由中添加可选尾部斜杠:
[Route("api/[controller]/")] - 若不需要HTTPS自动重定向,可注释或修改
UseHttpsRedirection配置:
// 注释该行禁用HTTPS重定向,或调整重定向规则 // app.UseHttpsRedirection();
3. 统一React端请求配置(避免代理冲突)
选择一种代理方式,不要同时混用craco代理与package.json proxy:
方案A:使用craco代理(推荐)
保留craco的devServer配置,修改axios实例为相对路径,让请求走代理:
// axios实例配置 export default axios.create({ baseURL: "/api", // 相对路径,由代理转发至后端 headers: { "Content-type": "application/json" // 移除Access-Control-*相关头,此类响应头由服务器设置,前端配置无效 } });
注意craco配置中的pathRewrite: { '^/api': '' }意味着后端实际接口路径为/schedule,需确保后端控制器路由匹配。
方案B:使用package.json proxy
删除craco中的代理配置,在package.json中添加:
"proxy": "http://localhost:5144"
axios实例配置:
export default axios.create({ baseURL: "/api", headers: { "Content-type": "application/json" } });
4. 验证预检请求
通过浏览器开发者工具Network标签,查看OPTIONS请求的响应:
- 确认响应头包含
Access-Control-Allow-Origin: http://localhost:3000 - 确认响应状态码为200,而非301/302重定向
额外注意事项
- 开发环境避免使用
*作为origin,明确指定前端地址更安全且减少潜在问题 - 前端不要设置
Access-Control-Allow-Origin等CORS相关响应头,此类头由服务器返回才有效 - 若后端启用HTTPS,需将代理target改为
https://localhost:5001,并保持secure: false(开发环境忽略证书)
内容的提问来源于stack exchange,提问作者user6408649

