将 fetch 与内容类型一起使用时出现 CORS 错误



我正在尝试从FireFox中的其他域向REST Web服务发送POST请求。 我为此使用了JavaScript"获取"功能。 我在 IIS 中托管 REST Web 服务。 在我在 JavaScript 中添加"Content-Type"标头之前,它工作正常。

FireFox 控制台中的 CORS 错误

请注意,如果我在控制台中启用 XHR,那么我可以看到将 fetch 与"内容类型"一起使用会导致 OPTIONS 请求。 但是,不使用"内容类型"会导致 POST 请求。 因此,正如文档所述,fetch 正在触发预检请求。 这些是错误:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://example.com/Service.svc/Request. (Reason: CORS preflight response did not succeed).
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://example.com/Service.svc/Request. (Reason: CORS request did not succeed).
TypeError: NetworkError when attempting to fetch resource.

带有 CORS 错误的 JavaScript

var body = '{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));

JavaScript没有CORS错误,但也没有内容类型

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

我正在使用"凭据:"包括",因为 REST Web 服务配置了基本身份验证。

REST Web service web.config(注意不同的域(

我添加了一些 CORS 配置,以使其他请求在 FireFox 中跨域工作。 但是,我找不到允许内容类型的正确配置:

<configuration>
...
<system.webServer>
<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>
...
</system.webServer>
...
</configuration>

如果没有"Content-Type"标头"application/json",REST Web 服务将无法工作。 如何解决这些错误?

旁注

使用 HTTP 而不是 HTTPS 使示例更容易(因为不需要证书(,但它也以纯文本形式发送基本身份验证的凭据

在Daniel A. White提到的问题中,选定的答案是解决方案,尽管略有修改。如何向 WCF 服务添加跨域支持。

旁注

我注意到当尚未修复时,对 OPTIONS 调用的不同响应:

  • 405 方法不允许:在 IIS 中使用匿名身份验证
  • 401 未经授权:在 IIS 中使用基本身份验证 但正如丹尼尔指出的那样,两种情况下的 CORS 错误都是相同的

这就是我修改 WCF REST Web 服务并摆脱 CORS 错误的方式:

全球.asax.cs

我还将 Global.asax.cs 文件添加到 Web 服务中。 但我没有在其中添加任何"访问控制允许标头",因为它似乎推翻了 web.config。 所以决定把它减少到最低限度:

protected void Application_BeginRequest(object sender, EventArgs e)
{
// prevent 401 unauthorized response to CORS preflight check
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.End();
}
}

网络.config

我也把它剃光到最低限度(确保你已经运行了AllManagedModulesForAllRequests="true">(

<configuration>
...
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
...
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://example.net" />
<add name="Access-Control-Allow-Credentials" value="true" />
<add name="Access-Control-Allow-Headers" value="Content-Type"/>
</customHeaders>
</httpProtocol>
...
</system.webServer>
...
</configuration>

最新更新