You need to enable JavaScript to run this app. .NET Core 3.1 WebApi PUT请求报Access-Control-Allow-Origin缺失
优惠活动
大模型
产品
解决方案
定价
更多

.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中注册的策略名称完全一致,避免覆盖全局策略。

内容的提问来源于stack exchange,提问作者Botnik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 03:45:04