配置IIS Express 8以启用CORS

11

我正在编写WCF服务,将被广泛使用的客户端需要处理跨域请求。 我在启用我的开发服务器接受这样的请求方面遇到了问题。情况如下:

  • 我正在Visual Studio 2012实例中运行WCF项目,使用IIS Express 8作为特定端口上的服务器。
  • 我在另一个Visual Studio 2012实例中运行客户端项目,也使用IIS Express 8作为服务器。该项目使用AJAX来消耗其他项目中的服务。

当我在IE中运行客户端项目时没有问题,因为IE不发送预检OPTIONS请求。但是当我在Chrome中运行它时,预检OPTIONS请求返回405 Method Not Allowed,Chrome放弃了服务。 Chrome的先前版本会忽略错误并继续进行实际的POST请求(或Get,等等...),但后来的版本似乎更加挑剔。

我也遇到了部署的WCF项目中的这个问题,并通过将OPTIONSVerbHandler移动到IIS中的Handler Mappings列表的顶部来解决它。

我应该指出,我正在使用我能想到的最慷慨的web.config设置来尝试允许CORS。例如,在WCF项目的配置中,我有:

<httpProtocol>
  <customHeaders>
    <remove name="X-Powered-By" />
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="*" />
    <add name="Access-Control-Allow-Methods" value="*" />
    <add name="X-Powered-By" value="*" />
  </customHeaders>
</httpProtocol>

无论如何,任何客户端跨源请求到运行的代码的WCF项目都会导致405错误。

有没有帮助设置WCF项目本身或IIS Express 8以启用CORS的任何帮助?

谢谢!


你是否正在使用WCF服务来进行REST?实际上,你可能想要移除OptionsVerbHandler并自己处理。或者,你可能想要暴露JSONP。我建议你使用ASP.Net Web-API - Aron
多年之后,现在可以在IIS Express上使用CORS模块了。https://blog.lextudio.com/how-to-install-microsoft-cors-module-for-iis-express-7ac24e4c3bc4 - Lex Li
5个回答

14

一旦你知道如何操作,你就可以为wcf启用cors,而且这可能非常简单。

从DavidG在更一般的问题“IIS上的cors”上的回答详细说明了所需的基本解决方案:

  • 首先,将OPTIONSVerbHandler配置为在.Net处理程序之前执行。

    1. 在IIS控制台中,选择“处理程序映射”(可在服务器级别或站点级别执行此操作。在站点级别上,它将重新定义您站点的所有处理程序,并忽略之后在服务器级别进行的任何更改。当然,在服务器级别上,这可能会破坏其他需要其自己选项动词处理的站点。)
    2. 在“操作”窗格中,选择“查看有序列表...”。寻找OPTIONSVerbHandler,并将其向上移动(需要多次点击...)。

    您还可以在web.config中执行此操作,即在<system.webServer><handlers>下重新定义所有处理程序。(使用<clear>然后将它们加回来,这正是IIS控制台为您完成的操作。顺便说一下,不需要要求此处理程序具有“读取”权限。)

  • 其次,为您的cors需求配置自定义http头,例如:

    <system.webServer>
      <httpProtocol>
        <customHeaders>
          <add name="Access-Control-Allow-Origin" value="*"/>
          <add name="Access-Control-Allow-Headers" value="Content-Type"/>
          <add name="Access-Control-Allow-Methods" value="POST,GET,OPTIONS"/>
        </customHeaders>
      </httpProtocol>
    </system.webServer>
    
    这个例子将它们设置为站点/应用程序/目录中所有请求的所有响应。如果您想将它们限制在某些URL上,请将其放入<location>标记中。
    您也可以在IIS控制台中添加那些自定义标头。这是一个基本的解决方案,因为它甚至会对不需要它的请求发送CORS标头,可能会使您的应用程序面临意外的使用情况。但是在WCF中,这似乎是最简单的解决方法。 对于MVC或WebAPI,我们可以通过代码(手动或使用WebAPI最新版本中可用的内置支持)处理OPTIONS动词和CORS标头。

我也遇到了同样的问题,我按照上述步骤进行尝试,但并未得到期望的结果。请求中所要求的头部信息和响应中所允许的头部信息一字不差地匹配,但仍然失败了。请帮忙解决。 - Siva Senthil
@SivaSenthil,如果在你的情况下OPTIONS请求的响应状态为200,则可能不再是IIS / WCF的问题。 - Frédéric
@Fredric,不幸的是OPTIONS请求失败了,状态码为400 - 错误请求。 - Siva Senthil
@SivaSenthil,看起来OPTIONSVerbHandler在.NET处理程序之前不会执行。如果您已经在服务器级别上设置了其执行顺序,请检查它在站点级别上是否被撤消。 - Frédéric

3
  • 仅对Access-Control-Allow-Origin有效。对于其他内容,您需要明确说明。例如:

Access-Control-Allow-Methods: GET、PUT、POST、DELETE

或者:

Access-Control-Allow-Methods: PUT、DELETE

因为规范中已经默认包含了GET和POST。


谢谢。但是,将web.config条目更改为以下内容: <add name="Access-Control-Allow-Methods" value="OPTIONS, POST" /> 没有任何效果。 - djo.dadof2

1
答案是,使WCF接受CORS预检请求所需的配置与IIS服务器无关; 相反,需要配置WCF项目以处理OPTIONS动词的HTTP请求。
简而言之:这很难做到。当涉及到端点时,WCF是万能的,因此不建议将其设置为仅处理一个(HTTP)非常特定的事情,尽管这可以完成。真正的解决方案是使用Web API,它是HTTP的大师,并且可以轻松地设置为执行CORS。

有时候找到答案的关键是限制可行答案的范围。这对我有帮助。谢谢。 - Manuel Hernandez

0

我不确定这是否像 djo.dadof2 所说的那样困难。上面的一个答案谈到了使用 IIS 控制台,但问题是关于 IIS Express 的。公平地说,它谈到了将 OPTIONSVerbHandler 移动到更高的位置,这实际上可能在 IIS Express 中起作用,但您必须清除所有处理程序并添加它们回来,而没有像 IIS 这样的控制台,很难知道要添加哪些处理程序。从这个答案中,Call WCF service from JQuery : cross-origin OPTIONS request gives error 400,您可以看到您真正需要做的就是在 Global.asax.cs 中处理 OPTIONS 请求,Application_BeginRequest。我添加了

        if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "content-type");

            HttpContext.Current.Response.End();
        }

还有

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="null" />
  </customHeaders>
</httpProtocol>

在 webconfig 的 system.webServer 部分,这对我有效。请注意,我在Access-Control-Allow-Headers头中使用了content-type来匹配 Firefox 发送的内容,并在Access-Control-Allow-Origin中使用了null,因为我正在从本地驱动器打开一个 HTML 页面。

0
我想提一下,截至目前为止,我不认为网络浏览器支持Access-Control-Allow-MethodsAccess-Control-Allow-Headers的*通配符值,尽管它在规范中有提到。
规范:

https://www.w3.org/TR/cors/
https://www.rfc-editor.org/rfc/rfc2616#section-4.2

请查看兼容性说明(更易读):

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers

鉴于上述更好的解决方案不可得,这意味着你必须明确地提供你想要允许的每个标头或方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接