.NET Core 3.1 WebApi PUT请求报Access-Control-Allow-Origin缺失
问题根因
POST请求能正常通行、PUT请求被CORS拦截,本质是两类请求的浏览器校验逻辑存在差异:
- 不带自定义头、Content-Type为text/plain/表单格式的POST属于CORS定义的简单请求,浏览器不会触发预检校验,直接把请求发送到后端,自然能正常处理。
- PUT请求属于非简单请求,浏览器会先发送
OPTIONS方法的预检请求校验跨域规则,如果预检请求拿不到合法的CORS响应头,会直接拦截后续的正式PUT请求,哪怕PUT接口本身的逻辑完全正常,也会抛出报错说缺少Access-Control-Allow-Origin响应头。
排查修复步骤
校验CORS中间件的管道顺序
.NET Core 3.1对CORS中间件的放置位置有严格要求:app.UseCors()必须放在app.UseRouting()之后、app.UseAuthentication()/app.UseAuthorization()/app.UseEndpoints()之前。如果顺序偏移,CORS中间件不会接管请求,自然不会给响应加上跨域允许头。
正确的管道顺序参考:app.UseRouting(); // CORS中间件必须放置在这个位置 app.UseCors("Policy2"); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => endpoints.MapControllers());你目前配置的Policy2本身逻辑完全合规,
AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader()足够覆盖PUT请求的校验要求。解决IIS层面的预检请求拦截问题
这是同机IIS托管场景下最容易触发的故障:IIS默认安装的WebDAV模块、静态请求处理模块会直接拦截OPTIONS方法的请求,直接返回405状态码,根本不会把请求转发到.NET Core的托管进程,你的CORS中间件完全没有机会处理这个预检请求。
修复操作:
在WebApi项目发布根目录的web.config的system.webServer节点下添加配置,移除WebDAV对请求的拦截,同时给OPTIONS、PUT等方法开放请求转发权限:<system.webServer> <modules> <remove name="WebDAVModule" /> </modules> <handlers> <remove name="WebDAV" /> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer>验证预检请求的实际返回
用Postman/curl工具直接给你的PUT接口地址发送OPTIONS方法的测试请求,检查返回头:- 是否包含
Access-Control-Allow-Origin值 Access-Control-Allow-Methods值是否包含PUT
如果请求直接返回405、或者没有上述响应头,说明请求被IIS层面拦截,没有到达你的应用程序。
- 是否包含
规避常见配置坑
- 不要在CORS策略中同时使用
AllowAnyOrigin()和AllowCredentials(),.NET Core 3.1会直接抛出运行时异常,导致CORS头无法正常写入响应。 - 不要手动在策略中添加
Access-Control-Allow-Origin响应头,比如你定义的Policy1的写法,会导致响应中出现重复的跨域头,直接触发浏览器的CORS校验失败。 - 如果使用控制器级别的
[EnableCors]属性,确保属性指定的策略名称和你在ConfigureServices中注册的策略名称完全一致,避免覆盖全局策略。
- 不要在CORS策略中同时使用
内容的提问来源于stack exchange,提问作者Botnik
相关产品推荐
相关产品推荐

