dotnet protocol_error ai_generated true

Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware: The CORS protocol does not allow a preflight request to have a body.

ID: dotnet/aspnet-core-cors-preflight-failure

Also available as: JSON · Markdown · 中文
85%Fix Rate
83%Confidence
1Evidence
2024-05-01First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
3.1 active
5.0 active
6.0 active
7.0 active
8.0 active

Root Cause

ASP.NET Core CORS middleware rejects a preflight OPTIONS request because it contains a body, which violates the CORS specification.

generic

中文

ASP.NET Core CORS 中间件拒绝包含请求体的预检 OPTIONS 请求,因为违反了 CORS 规范。

Official Documentation

https://learn.microsoft.com/en-us/aspnet/core/security/cors

Workarounds

  1. 95% success Ensure the client does not send a body in OPTIONS preflight requests. For fetch API, avoid setting body on OPTIONS. Example: fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) and let the browser handle preflight without body.
    Ensure the client does not send a body in OPTIONS preflight requests. For fetch API, avoid setting body on OPTIONS. Example: fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) and let the browser handle preflight without body.
  2. 85% success Configure CORS middleware to handle OPTIONS requests early by placing app.UseCors() before app.UseRouting() and app.UseEndpoints() in Startup.cs or Program.cs.
    Configure CORS middleware to handle OPTIONS requests early by placing app.UseCors() before app.UseRouting() and app.UseEndpoints() in Startup.cs or Program.cs.
  3. 75% success Use a custom middleware that reads and discards the body for OPTIONS requests before CORS middleware runs. Example: app.Use(async (context, next) => { if (context.Request.Method == "OPTIONS") { context.Request.Body = Stream.Null; } await next(); });
    Use a custom middleware that reads and discards the body for OPTIONS requests before CORS middleware runs. Example: app.Use(async (context, next) => { if (context.Request.Method == "OPTIONS") { context.Request.Body = Stream.Null; } await next(); });

中文步骤

  1. 确保客户端在 OPTIONS 预检请求中不发送请求体。对于 fetch API,避免在 OPTIONS 中设置 body。示例:fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }) 并让浏览器处理无请求体的预检。
  2. 配置 CORS 中间件以提前处理 OPTIONS 请求,在 Startup.cs 或 Program.cs 中将 app.UseCors() 放在 app.UseRouting() 和 app.UseEndpoints() 之前。
  3. 使用自定义中间件在 CORS 中间件运行之前读取并丢弃 OPTIONS 请求的请求体。示例:app.Use(async (context, next) => { if (context.Request.Method == "OPTIONS") { context.Request.Body = Stream.Null; } await next(); });

Dead Ends

Common approaches that don't work:

  1. Modifying the CORS policy to allow all headers and methods without addressing the body issue 90% fail

    CORS policy configuration does not affect the protocol-level restriction on preflight request bodies.

  2. Disabling CORS middleware entirely in development 70% fail

    Disabling CORS removes cross-origin protection and may cause security issues; also does not fix the root cause for production.

  3. Adding custom middleware to ignore the body on OPTIONS requests 60% fail

    Custom middleware may not run before CORS middleware in the pipeline, or may interfere with other request handling.