React + ASP.NET Core 前后端项目跨域请求被拦截问题求助
问题原因
- 允许源配置不匹配:后端配置的允许跨域源为
http://localhost:3000,如果前端实际运行地址为HTTPS协议、端口不是3000,就会触发跨域拦截 - 自签SSL证书未被信任:本地ASP.NET Core使用的自签HTTPS证书不被浏览器信任,导致预检OPTIONS请求被直接拦截,出现CORS请求失败的报错
- 认证中间件拦截预检请求:如果接口加了
[Authorize]认证特性,浏览器发起的CORS预检OPTIONS请求不会携带认证头,会被认证中间件拦截返回401/403,导致跨域校验失败 - AllowCredentials配置不匹配:后端CORS开启了
AllowCredentials(),但前端fetch请求未携带对应的credentials配置,导致跨域校验不通过 - 中间件顺序错误:如果认证/授权中间件放在了CORS中间件之前,会导致CORS策略还没生效就被认证拦截,预检请求失败
解决方法
1. 修正允许源配置
确认React前端实际运行的地址(浏览器地址栏显示的完整地址,包括协议、域名、端口),保证和WithOrigins内的配置完全一致,多个允许源可逗号分隔:
builder.WithOrigins("http://localhost:3000", "https://localhost:3000") // 按实际前端地址填写 .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials();
注意:允许源地址末尾不要加斜杠,例如不要写成
http://localhost:3000/
2. 信任本地自签SSL证书
直接在浏览器地址栏访问一次后端HTTPS地址https://localhost:44316,点击「高级」→「继续访问localhost(不安全)」,完成证书信任后再发起前端请求。
也可以暂时将前端请求地址改为后端的HTTP端口,避开HTTPS证书问题。
3. 调整中间件顺序,放行预检请求
在Configure方法中调整中间件顺序,确保CORS中间件放在认证/授权中间件之前:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseRouting(); // CORS必须放在UseRouting之后,认证授权之前 app.UseCors("myPolicy"); // 加上缺失的认证、授权中间件 app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapHub<ChatHub>("/chat"); }); }
如果使用JWT认证,可以在JWT配置中添加OPTIONS请求的放行逻辑,避免预检请求被拦截:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { // 你原有JWT配置保持不变 options.Events = new JwtBearerEvents { OnMessageReceived = context => { // 放行OPTIONS请求的认证校验 if (context.Request.Method == HttpMethods.Options) { context.Success(); } return Task.CompletedTask; } }; });
4. 匹配前端fetch配置
后端开启AllowCredentials()的情况下,前端fetch请求需要添加credentials: 'include'参数:
const submitRegisterForm = async (e) => { e.preventDefault(); await fetch( "https://localhost:44316/api/auth/register",{ method: 'POST', headers: {"Content-Type": "application/json"}, credentials: 'include', // 新增该行配置 body: JSON.stringify({ name, email, password, role, }) }); setRedirectTo(true); };
临时测试方案
可以暂时将CORS策略改为允许所有源,快速定位是否是源配置问题:
builder.AllowAnyOrigin() .AllowAnyHeader() .AllowAnyMethod(); // 注意:使用AllowAnyOrigin时必须删除AllowCredentials(),两者不兼容
如果修改后请求正常,说明问题出在允许源配置上,排查后改回指定源即可。
内容的提问来源于stack exchange,提问作者Rabner Casandara
相关产品推荐
相关产品推荐

