.NET 6.0 API(Blazor WASM)PUT/DELETE请求CORS失败求助
针对你遇到的PUT/DELETE跨域报错、POST/GET正常,且本地环境无问题的情况,结合你的代码和排查动作,提供以下解决方向:
1. 处理预检OPTIONS请求被认证拦截的问题
PUT/DELETE属于非简单请求,浏览器会先发OPTIONS预检请求,而JWT认证中间件可能会对OPTIONS请求进行token校验(但OPTIONS请求不会携带token),导致返回401,进而触发CORS错误。
解决步骤:
在JWT认证配置中添加事件,忽略OPTIONS请求的token验证:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { // 原有配置... options.Events = new JwtBearerEvents { OnMessageReceived = context => { if (context.Request.Method == HttpMethod.Options.Method) { context.Response.StatusCode = StatusCodes.Status200OK; return Task.CompletedTask; } return Task.CompletedTask; } }; });
或者在认证中间件前添加全局OPTIONS请求处理:
// 放在UseRouting之后、UseCors之前 app.Use(async (context, next) => { if (context.Request.Method == HttpMethod.Options.Method) { context.Response.StatusCode = StatusCodes.Status200OK; return; } await next(); }); app.UseCors(); app.UseAuthentication(); // ...后续中间件
2. 检查生产环境反向代理的配置限制
如果生产环境使用了Nginx、Apache等反向代理,可能代理层未配置允许PUT/DELETE方法,或未正确传递CORS响应头。
以Nginx为例,需在对应location块中添加:
# 允许跨域方法 add_header Access-Control-Allow-Methods 'GET, POST, PUT, DELETE, OPTIONS'; # 允许跨域头 add_header Access-Control-Allow-Headers 'Authorization, Content-Type'; # 直接响应OPTIONS请求 if ($request_method = OPTIONS) { return 204; }
3. 验证CORS策略的应用范围
虽然你配置了默认CORS策略,但可以尝试在控制器或Action上显式添加[EnableCors]特性,确保策略被正确应用:
[ApiController] [Route("api/[controller]")] [EnableCors] // 启用默认CORS策略 public class YourController : ControllerBase { // ... }
同时,可显式指定允许的方法,替代AllowAnyMethod():
policy.WithMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");
4. 排查全局异常处理中间件的影响
你的代码中调用了app.ConfigureExceptionHandler(),需确保该中间件不会拦截OPTIONS请求的响应,导致CORS头未被正确添加。可以暂时注释该中间件,测试是否解决问题,若解决则调整异常处理逻辑,确保OPTIONS请求的响应包含CORS头。
5. 检查HttpsRedirection的潜在影响
生产环境启用了app.UseHttpsRedirection(),若前端请求是HTTP协议,会被重定向到HTTPS,可能导致预检请求失败。可以暂时注释该中间件测试,或配置HttpsRedirection的允许规则,确保跨域请求的重定向不会破坏CORS流程。
内容的提问来源于stack exchange,提问作者daniel

