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

时间:2015-06-05 08:28:29

标签: wcf http cors options httpverbs

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

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

在IE中一切都很好,(因为我认为IE不会将端口视为不同的来源)但是Opera和Firefox都会发送预检OPTIONS请求。

我已将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请求中所期望的任何细节,所以回复标准的“你发错了”响应。

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

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

然后预检OPTIONS得到“405 - Method not allowed”响应。

我做错了什么?我应该配置我的服务来回复OPTIONS请求,如果是,那么正确的响应是什么?

我假设我可以在服务中选择请求类型并使用200回复​​ - 如果动词是OPTIONS然后重新发送实际的POST,那么,如果我手动执行此操作,浏览器将只发送选项再次作为新请求。

编辑:

我刚刚发现这篇帖子,有必要删除WEbDAV处理程序: CORS 405 (Method Not Allowed)

但它没有帮助。

还有一篇关于将OPTIONSHttpVerb处理程序移动到列表顶部并赋予其“读取”权限的帖子,但这也无济于事。

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

OPTIONS响应

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

2 个答案:

答案 0 :(得分:1)

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

它不适合我的原因是因为响应标头是套管而请求标头不是,即:

请求标题:

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

响应标题:

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

这违反了HTTP / 1.1标准BTW,请参阅https://stackoverflow.com/a/5259004/1602497

答案 1 :(得分:0)

看起来这都是我自己的错。 我正在使用外卡:

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

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

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

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

所以我只是检查了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.......

希望能帮助其他人。