CORS请求预检请求,以用户代码结尾

CORS request preflight request, ending in user code

我有一组 WCF Web 服务 运行 在仅供内部使用的界面上,许多其他网站(也仅供内部使用)调用这些服务。域名匹配,只是端口号不同

我正在向这些 Web 服务发出 AJAX POST 请求,因为它们在技术上不是同一来源(不同端口),所以我正在使用 CORS。

在 IE 中一切正常(因为我相信 IE 不会将端口视为不同的来源)但是 Opera 和 Firefox 都会发送预检选项请求。

我已将 Web 服务配置为通过 web.config 文件接受这些请求:

<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="*" />

我还在我的服务上设置了接口以接受任何 HTTP 动词:

[OperationContract(Name = "H2dbDataExport")]
[WebInvoke(Method = "*", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string H2dbDataExport(string action, string username, exportDetails data);

然而,这会导致底层服务被调用,并且因为它没有找到任何它期望在 POST 请求中使用标准 "You sent something wrong" 响应进行回复的详细信息。

如果我将服务更改为仅接受 POST 请求 - 这实际上是唯一的响应,它将通过以下方式响应:

[WebInvoke(Method = "POST", etc.......

然后预检选项收到“405 - 方法不允许”响应。

我做错了什么?我应该配置我的服务以回复 OPTIONS 请求吗?如果是这样,正确的回复是什么?

我假设我可以在服务中选择请求类型并回复 200 - 好的,如果动词是 OPTIONS 然后重新发送实际的 POST - 但如果我手动这样做肯定浏览器将再次发送选项作为新请求。

编辑:

我刚刚发现这个 post,关于删除 WEBDAV 处理程序: CORS 405 (Method Not Allowed)

但是没有用。

还有一个 post 关于将 OPTIONSHttpVerb 处理程序移动到列表顶部并赋予它 "Read" 权限,但这也没有帮助。

编辑 2: 实际上移动 OPTIONSHttpVerb 确实有帮助,它不再调用 Web 服务,但 IIS 确实以 200 - OK 响应。然而,这个响应仍然在浏览器的客户端代码中结束,所以没有帮助。

选项响应

HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/7.5
Public: OPTIONS, TRACE, GET, HEAD, POST
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Max-Age: 1728000
Date: Fri, 05 Jun 2015 10:34:29 GMT
Content-Length: 0

看来这都是我自己的错。 我使用 wild-card 用于:

<add name="Access-Control-Allow-Headers" value="*" />

这显然是不允许的。如果请求指定 Access-Control-Request-Headers,则服务器必须使用相同的列表进行回复。

https://whosebug.com/a/13147554/1286358

http://www.html5rocks.com/en/tutorials/cors/

所以我只是检查了 headers 随 OPTIONS 请求一起发送的内容,并将它们设置为接受。

预检请求中有这一行:

Access-Control-Request-Headers: accept, content-type

所以我更改了 web.config 以匹配:

<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="accept, content-type" />

现在可以使用了。

这也让我能够将服务改回(正确地)仅接受 POST 请求。

[WebInvoke(Method = "POST", etc.......

希望对您有所帮助 some-one 否则。

没有足够的业力来评论,所以我会把它放在这里供像我一样来到这个问题和答案的人,因为 IE11 不会在成功的 OPTIONS 请求后发送 POST 请求(200 次)

它对我不起作用的原因是因为响应 headers 被封装而请求 headers 没有,即:

请求Headers:

Access-Control-Request-Headers: content-type, accept

回应Headers:

Access-Control-Allow-Headers: Content-Type, Accept

这违反了 HTTP/1.1 标准顺便说一句,请参阅 https://whosebug.com/a/5259004/1602497