在 IIS7 上启用跨域资源共享

IT技术 javascript iis-7 xmlhttprequest cors
2021-02-01 19:50:06

我最近遇到了将 Javascript 请求发布到另一个域的问题。默认情况下,不允许 XHR 发布到其他域。

按照http://enable-cors.org/的说明,我在另一个域上启用了它。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
 <system.webServer>
  <httpProtocol>
    <customHeaders>
      <add name="Access-Control-Allow-Origin" value="*" />
      <add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
      <add name="Access-Control-Allow-Headers" value="Content-Type" />
    </customHeaders>
  </httpProtocol>
 </system.webServer>
</configuration>

在此处输入图片说明

现在一切正常,但是在发回工作 200 响应之前它仍然返回 405 响应。

Request URL:http://testapi.nottherealsite.com/api/Reporting/RunReport
Request Method:OPTIONS
Status Code:405 Method Not Allowed
Request Headersview source
Accept:*/*
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Access-Control-Request-Headers:origin, content-type, accept
Access-Control-Request-Method:POST
Connection:keep-alive
Host:testapi.nottherealsite.com
Origin:http://test.nottherealsite.com
Referer:http://test.nottherealsite.com/Reporting
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1
Response Headersview source
Access-Control-Allow-Headers:Content-Type
Access-Control-Allow-Methods:GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Origin:*
Allow:POST
Cache-Control:private
Content-Length:1565
Content-Type:text/html; charset=utf-8
Date:Tue, 18 Sep 2012 14:26:06 GMT
Server:Microsoft-IIS/7.5
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET

更新:3/02/2014

MSDN 杂志中有一篇最近更新的文章。详细说明 ASP.NET Web API 2 中的 CORS 支持。

http://msdn.microsoft.com/en-us/magazine/dn532203.aspx

6个回答

这可能是 IIS 7“处理”HTTP OPTIONS 响应而不是您的应用程序指定它的情况。要确定这一点,在 IIS7 中,

  1. 转到您站点的处理程序映射。

  2. 向下滚动到“OPTIONSVerbHandler”。

  3. 将“ProtocolSupportModule”更改为“IsapiHandler”

  4. 设置可执行文件:%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll

现在,当发送 HTTP OPTIONS 动词时,您上面的配置条目应该会启动。

或者,您可以在您的 BeginRequest 方法中响应 HTTP OPTIONS 动词。

    protected void Application_BeginRequest(object sender,EventArgs e)
    {
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");

        if(HttpContext.Current.Request.HttpMethod == "OPTIONS")
        {
            //These headers are handling the "pre-flight" OPTIONS call sent by the browser
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
            HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000" );
            HttpContext.Current.Response.End();
        }

    }
经过 2 天的研究,使用基于的替代解决方案Application_BeginRequest是我解决问题的唯一方法。我尝试使用其他方法customHeadersstackoverflow.com/a/19091291/827168),删除OPTIONSVerbHandler处理程序,删除WebDAVmodule和处理程序(stackoverflow.com/a/20705500/827168),但没有一个对我有用。希望这会帮助其他人。并感谢@Mendhak 的回答!
2021-03-11 19:50:06
对我来说,以与 OP 相同的方式将其添加到 web.config 是唯一的方法。Global.asax/BeginRequest 不起作用。
2021-03-15 19:50:06
我尝试了这两种方法,但只有 BeginREquest 方法对我有用。谢谢@Shah
2021-03-18 19:50:06
该死的 ASP.NET 和 IIS。为什么配置一个像 CORS 这样简单的概念就这么难?这真的很简单。只需阅读 W3C 的规范。你可以在 10 分钟内学会它,然后你需要 10 天的时间来弄清楚如何在 ASP.NET 和 IIS 中配置它。
2021-03-22 19:50:06
@Mendhak,你救了我的命哈哈。我添加的唯一内容总是HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");因为共享身份验证 cookie。
2021-03-27 19:50:06

我不能发表评论,所以我必须把它放在一个单独的答案中,但这与 Shah 接受的答案有关。

我最初通过在 IIS 中重新配置 OPTIONSVerbHandler 来遵循 Shah 的回答(谢谢!),但是当我重新部署我的应用程序时,我的设置被恢复了。

我最终删除了 Web.config 中的 OPTIONSVerbHandler。

<handlers>
    <remove name="OPTIONSVerbHandler"/>
</handlers>
这个答案对我在 IIS7 下部署的 MVC6 web api 项目有帮助。在生产机器中,此选项工作正常,但如上所述,我必须在另一个终端上迁移期间为同一项目删除它!谢谢
2021-04-07 19:50:06
对于那些每天不使用 web.config 的人来说,这在“<system.webServer>”中
2021-04-10 19:50:06

我发现在http://help.infragistics.com/Help/NetAdvantage/jQuery/2013.1/CLR4.0/html/igOlapXmlaDataSource_Configuring_IIS_for_Cross_Domain_OLAP_Data.html 中找到的信息对于在 IIS 7 中为 WCF 服务设置 HTTP OPTIONS 非常有帮助。

我将以下内容添加到我的 web.config,然后将 IIS 7 'hander mappings' 列表中的 OPTIONSVerbHandler 移动到列表顶部。我还通过双击处理程序映射部分中的处理程序,然后单击“请求限制”,然后单击访问选项卡,授予 OPTIONSVerbHander 读取访问权限。

不幸的是,我很快发现 IE 似乎不支持向其XDomainRequest对象添加标头(将 Content-Type 设置为 text/xml 并添加 SOAPAction 标头)。

只是想分享这个,因为我花了一天的大部分时间寻找如何处理它。

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
            <add name="Access-Control-Allow-Methods" value="GET,POST,OPTIONS" />
            <add name="Access-Control-Allow-Headers" value="Content-Type, soapaction" />
        </customHeaders>
    </httpProtocol>
</system.webServer>
指定来源更安全。看: <add name="Access-Control-Allow-Origin" value="http://my.origin.host" />
2021-03-13 19:50:06
看起来当前版本的 Chrome 不再考虑在具有错误 http 状态的响应中收到的 cors 标头。所以在这种情况下它不会再继续执行跨域请求。恕我直言,这是一种更好的行为。
2021-03-21 19:50:06
感谢您的回复。如果您浏览了上面的响应,请不要忘记如上所述授予 OPTIONSVerbHander 读取访问权限。
2021-03-24 19:50:06
Shah 的 IIS isapiHandler 配置不起作用,但我没有尝试编程方式。但是我也发现 web.config 中的上述 WCF 配置可以解决问题。Chrome 仍然发送 OPTIONS 并第一次获得 405,但随后它发布了另一个请求,这是正确的。
2021-04-08 19:50:06

DavidG 的答案详细阐述,这与基本解决方案所需的内容非常接近:

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

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

    您也可以在 web.config 中通过重新定义下的所有处理程序来执行此操作<system.webServer><handlers><clear>然后将<add ...>它们返回,这就是 IIS 控制台为您所做的)(顺便说一句,无需为此处理程序请求“读取”权限。)

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

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

    您也可以在 IIS 控制台中执行此操作。

这是一个基本的解决方案,因为它甚至会根据不需要它的请求发送 cors 标头。但是使用 WCF,它看起来是最简单的。

使用 MVC 或 webapi,我们可以改为通过代码处理 OPTIONS 动词和 cors 标头(“手动”或使用最新版本的 webapi 中提供的内置支持)。

这对我有用。我不喜欢每个处理程序最终都在 Web.config 中重新定义,但可惜这似乎是我需要做的才能使我们的 WCF 服务 CORS 启用。+1
2021-03-29 19:50:06

405 响应是“方法不允许”响应。听起来您的服务器没有正确配置为处理 CORS 预检请求。你需要做两件事:

1) 启用 IIS7 以响应 HTTP OPTIONS 请求。您收到 405 是因为 IIS7 拒绝了 OPTIONS 请求。我不知道该怎么做,因为我不熟悉 IIS7,但 Stack Overflow 上可能还有其他人这样做。

2) 配置您的应用程序以响应 CORS 预检请求。您可以通过Access-Control-Allow-Origin在该<customHeaders>部分中的行下方添加以下两行来完成此操作

<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />

您可能需要Access-Control-Allow-Headers根据您的请求要求的标头向该部分添加其他值你有发出请求的示例代码吗?

您可以在此处了解有关 CORS 和 CORS 预检的更多信息:http : //www.html5rocks.com/en/tutorials/cors/