You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

添加Content-Type后Fetch跨域请求CORS错误(IIS部署)求助

这个问题我之前踩过好几次坑!核心原因是你添加Content-Type: application/json后,浏览器把你的POST请求判定为非简单请求,会自动发送一个OPTIONS预请求做权限校验。但你的服务开启了Basic Authentication,而浏览器默认不会在OPTIONS预请求里携带认证凭据,导致IIS返回401未授权,直接触发CORS错误。

下面是一步步的解决方案:

1. 让IIS允许OPTIONS请求跳过Basic认证

因为OPTIONS预请求是浏览器自动发起的,不可能携带用户的Basic Auth信息,所以必须配置IIS对OPTIONS请求放行,不需要认证。你可以在web.config里添加如下配置:

<configuration>
  ...
  <system.webServer>
    <!-- 保留已有CORS自定义头配置 -->
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="http://example.net" />
        <add name="Access-Control-Allow-Methods" value="OPTIONS,POST"/>
        <add name="Access-Control-Allow-Credentials" value="true" />
        <add name="Access-Control-Allow-Headers" value="Content-Type"/>
      </customHeaders>
    </httpProtocol>
    
    <!-- 新增:允许OPTIONS请求匿名访问 -->
    <security>
      <authorization>
        <add accessType="Allow" users="*" verbs="OPTIONS"/>
      </authorization>
    </security>
    ...
  </system.webServer>

  <!-- 如果是ASP.NET框架,还需要在system.web节点添加规则 -->
  <system.web>
    <authorization>
      <allow verbs="OPTIONS" users="*"/>
    </authorization>
  </system.web>
  ...
</configuration>

2. 验证OPTIONS请求的响应

配置完后,打开浏览器开发者工具的Network标签,重新触发请求,查看OPTIONS请求的响应:

  • 状态码必须是200或204(绝对不能是401未授权)
  • 响应头里必须包含这些字段:
    • Access-Control-Allow-Origin: http://example.net(必须和你的请求源完全一致,不能用*,因为你启用了credentials:include)
    • Access-Control-Allow-Credentials: true
    • Access-Control-Allow-Methods: OPTIONS,POST
    • Access-Control-Allow-Headers: Content-Type

3. 修正请求体的JSON格式(可选但推荐)

你的请求体'{ID:2, Name:"test reqx"}'不是严格的JSON格式(键名没有用双引号),虽然这不是CORS错误的直接原因,但可能导致服务端解析失败。建议用JSON.stringify生成标准JSON:

var body = JSON.stringify({ID:2, Name:"test reqx"});
var url = "http://example.com/Service.svc/Request";
var init = {
  credentials:"include", 
  method:"POST", 
  headers:{
    "Content-Type":"application/json",
    "Accept":"application/json"
  }, 
  body:body
};
fetch(url,init)
 .then(response => response.text())
 .then(data => console.log(data));

补充:为什么之前不加Content-Type就正常?

因为不带Content-Type: application/json时,请求属于简单请求,浏览器不会发送OPTIONS预请求,直接发送POST并携带凭据,所以能通过认证。但这种情况下服务端可能无法正确解析JSON请求体,所以必须解决OPTIONS预请求的认证问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:32:55