【问题标题】:CORS request preflight request, ending in user codeCORS 请求预检请求,以用户代码结尾
【发布时间】:2015-08-20 03:01:25
【问题描述】:

我有一组 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 - 但如果我手动执行此操作,浏览器肯定会发送OPTIONS 再次作为它的新请求。

编辑:

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

但这并没有帮助。

还有一篇关于将 OPTIONSHttpVerb 处理程序移至列表顶部并为其授予“读取”权限的帖子,但这也没有帮助。

编辑 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

【问题讨论】:

    标签: wcf http cors options httpverbs


    【解决方案1】:

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

    它对我不起作用的原因是因为响应标头是大小写的,而请求标头不是,即:

    请求标头:

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

    响应标头:

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

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

    【讨论】:

      【解决方案2】:

      看来都是我自己的错。 我将通配符用于:

      <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.......
      

      希望对其他人有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-21
        • 2016-02-05
        • 2021-03-27
        • 1970-01-01
        • 2018-02-12
        • 2015-08-04
        • 2013-09-13
        相关资源
        最近更新 更多