在 IIS7 上启用跨域资源共享

Posted

技术标签:

【中文标题】在 IIS7 上启用跨域资源共享【英文标题】:enabling cross-origin resource sharing on IIS7 【发布时间】:2012-09-09 14:54:32 【问题描述】:

我最近遇到了将 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

更新:2014 年 3 月 2 日

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

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

【问题讨论】:

它解决了我获取 jQuery bootgrid 插件的错误排序图标的问题想要从 Bootstrap 字体文件夹加载 glyphicons-halflings-regular.woff 【参考方案1】:

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

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

2) 配置您的应用程序以响应 CORS 预检请求。您可以通过在&lt;customHeaders&gt; 部分的Access-Control-Allow-Origin 行下方添加以下两行来做到这一点:

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

【讨论】:

【参考方案2】:

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

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

    向下滚动到“OPTIONSVerbHandler”。

    将“ProtocolSupportModule”更改为“IsapiHandler”

    设置可执行文件: %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();
        

    

【讨论】:

我尝试了这两种方法,但只有 BeginREquest 方法适合我。谢谢@Shah 对我来说,以与 OP 相同的方式将其添加到 web.config 是唯一的方法。 Global.asax/BeginRequest 不起作用。 经过 2 天的研究,使用基于 Application_BeginRequest 的替代解决方案是我解决问题的唯一方法。我尝试了使用customHeaders (***.com/a/19091291/827168)、删除OPTIONSVerbHandler 处理程序、删除WebDAV 模块和处理程序(***.com/a/20705500/827168) 的其他方法,但没有一个对我有用。希望这对其他人有所帮助。感谢@Mendhak 的回答! 该死的 ASP.NET 和 IIS。为什么配置像 CORS 这样的简单概念会这么难?这真的很简单。只需阅读 W3C 的规范。 10分钟就能学会,然后你需要10天搞清楚如何在ASP.NET和IIS中配置。 @Mendhak,你救了我的命,哈哈。由于共享身份验证cookie,我唯一添加的始终是HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");【参考方案3】:

我发现在 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>

【讨论】:

Shah 的 IIS isapiHandler 配置不起作用,不过我没有尝试编程方式。但是,我还发现 web.config 中的上述 WCF 配置起到了作用。 Chrome 仍然发送 OPTIONS 并第一次获得 405,但随后它 POST 另一个请求,这是正确的。 当前版本的 Chrome 似乎不再考虑在 HTTP 状态错误的响应中收到的 cors 标头。所以在这种情况下不会再继续执行跨域请求了。这是一个更好的行为恕我直言。 感谢您的回复。如果您浏览了上面的回复,请不要忘记如上所述授予 OPTIONSVerbHander 读取权限。 指定来源更安全。看:&lt;add name="Access-Control-Allow-Origin" value="http://my.origin.host" /&gt;【参考方案4】:

我无法发布 cmets,因此我必须将其放在单独的答案中,但这与 Shah 接受的答案有关。

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

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

<handlers>
    <remove name="OPTIONSVerbHandler"/>
</handlers>

【讨论】:

对于那些不每天使用 web.config 的人来说,这在“”中 这个答案帮助我部署在 IIS7 下的 MVC6 web api 项目。在生产机器中,此选项工作正常,但如上所述,我必须在另一个终端迁移期间为同一个项目删除它!谢谢【参考方案5】:

从DavidG answer 开始详细说明,这非常接近基本解决方案所需的内容:

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

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

您也可以在 web.config 中通过重新定义 &lt;system.webServer&gt;&lt;handlers&gt; 下的所有处理程序来执行此操作(&lt;clear&gt; 然后将 &lt;add ...&gt; 他们返回,这就是 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【参考方案6】:

使用 ASP.net Web API 2 通过 nuget 安装 Microsoft ASP.NET Cross Origin 支持。

http://enable-cors.org/server_aspnet.html

public static void Register(HttpConfiguration config)

 var enableCorsAttribute = new EnableCorsAttribute("http://mydomain.com",
                                                   "Origin, Content-Type, Accept",
                                                   "GET, PUT, POST, DELETE, OPTIONS");
        config.EnableCors(enableCorsAttribute);

【讨论】:

你知道programmatically有没有办法设置EnableCorsAttribute的第一个“ORIGIN”参数?假设不是在 Register 中,而是针对传入的每个单独的 HTTP 请求。检测它的来源,确保它是好的(检查一些已批准的列表)然后返回带有 Access-Allow-Control-Origin="thatdomain.com" 的响应? @安德鲁【参考方案7】:

Alsalaam Aleykum。

第一种方法是按照此链接中的说明进行操作:

http://help.infragistics.com/Help/NetAdvantage/jQuery/2013.1/CLR4.0/html/igOlapXmlaDataSource_Configuring_IIS_for_Cross_Domain_OLAP_Data.html

对应这些配置:

<handlers>
  <clear />
  <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" type="" modules="ProtocolSupportModule" scriptProcessor="" resourceType="Unspecified" requireAccess="Read" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
  <add name="xamlx-ISAPI-4.0_64bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="4194304" />
  <add name="xamlx-ISAPI-4.0_32bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="4194304" />
  <add name="xamlx-Integrated-4.0" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" modules="ManagedPipelineHandler" scriptProcessor=""
  resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="rules-ISAPI-4.0_64bit" path="*.rules" verb="*" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness64"
  responseBufferLimit="4194304" />
  <add name="rules-ISAPI-4.0_32bit" path="*.rules" verb="*" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness32"
  responseBufferLimit="4194304" />
  <add name="rules-Integrated-4.0" path="*.rules" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" modules="ManagedPipelineHandler"
  scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="xoml-ISAPI-4.0_64bit" path="*.xoml" verb="*" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness64"
  responseBufferLimit="4194304" />
  <add name="xoml-ISAPI-4.0_32bit" path="*.xoml" verb="*" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness32"
  responseBufferLimit="4194304" />
  <add name="xoml-Integrated-4.0" path="*.xoml" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" modules="ManagedPipelineHandler"
  scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="svc-ISAPI-4.0_64bit" path="*.svc" verb="*" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness64"
  responseBufferLimit="4194304" />
  <add name="svc-ISAPI-4.0_32bit" path="*.svc" verb="*" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness32"
  responseBufferLimit="4194304" />
  <add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" modules="ManagedPipelineHandler" scriptProcessor=""
  resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="ISAPI-dll" path="*.dll" verb="*" type="" modules="IsapiModule" scriptProcessor="" resourceType="File" requireAccess="Execute" allowPathInfo="true" preCondition="" responseBufferLimit="4194304" />
  <add name="AXD-ISAPI-4.0_64bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="PageHandlerFactory-ISAPI-4.0_64bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="SimpleHandlerFactory-ISAPI-4.0_64bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script"
  allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="WebServiceHandlerFactory-ISAPI-4.0_64bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script"
  allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_64bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script"
  allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_64bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script"
  allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="aspq-ISAPI-4.0_64bit" path="*.aspq" verb="*" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness64"
  responseBufferLimit="0" />
  <add name="cshtm-ISAPI-4.0_64bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="cshtml-ISAPI-4.0_64bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="vbhtm-ISAPI-4.0_64bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="vbhtml-ISAPI-4.0_64bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="TraceHandler-Integrated-4.0" path="trace.axd" verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TraceHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0"
  responseBufferLimit="4194304" />
  <add name="WebAdminHandler-Integrated-4.0" path="WebAdmin.axd" verb="GET,DEBUG" type="System.Web.Handlers.WebAdminHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0"
  responseBufferLimit="4194304" />
  <add name="AssemblyResourceLoader-Integrated-4.0" path="WebResource.axd" verb="GET,DEBUG" type="System.Web.Handlers.AssemblyResourceLoader" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="PageHandlerFactory-Integrated-4.0" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.PageHandlerFactory" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="SimpleHandlerFactory-Integrated-4.0" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="System.Web.UI.SimpleHandlerFactory" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="WebServiceHandlerFactory-Integrated-4.0" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" modules="ManagedPipelineHandler"
  scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="HttpRemotingHandlerFactory-rem-Integrated-4.0" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="HttpRemotingHandlerFactory-soap-Integrated-4.0" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="System.Runtime.Remoting.Channels.Http.HttpRemotingHandlerFactory, System.Runtime.Remoting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
  modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="aspq-Integrated-4.0" path="*.aspq" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0"
  responseBufferLimit="4194304" />
  <add name="cshtm-Integrated-4.0" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0"
  responseBufferLimit="4194304" />
  <add name="cshtml-Integrated-4.0" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0"
  responseBufferLimit="4194304" />
  <add name="vbhtm-Integrated-4.0" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0"
  responseBufferLimit="4194304" />
  <add name="vbhtml-Integrated-4.0" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" type="System.Web.HttpForbiddenHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0"
  responseBufferLimit="4194304" />
  <add name="ScriptHandlerFactoryAppServices-Integrated-4.0" path="*_AppService.axd" verb="*" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" modules="ManagedPipelineHandler"
  scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="ScriptResourceIntegrated-4.0" path="*ScriptResource.axd" verb="GET,HEAD" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" modules="ManagedPipelineHandler"
  scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="4194304" />
  <add name="AXD-ISAPI-4.0_32bit" path="*.axd" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="PageHandlerFactory-ISAPI-4.0_32bit" path="*.aspx" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="SimpleHandlerFactory-ISAPI-4.0_32bit" path="*.ashx" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="WebServiceHandlerFactory-ISAPI-4.0_32bit" path="*.asmx" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script"
  allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="HttpRemotingHandlerFactory-rem-ISAPI-4.0_32bit" path="*.rem" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script"
  allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="HttpRemotingHandlerFactory-soap-ISAPI-4.0_32bit" path="*.soap" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script"
  allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="aspq-ISAPI-4.0_32bit" path="*.aspq" verb="*" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false" preCondition="classicMode,runtimeVersionv4.0,bitness32"
  responseBufferLimit="0" />
  <add name="cshtm-ISAPI-4.0_32bit" path="*.cshtm" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="cshtml-ISAPI-4.0_32bit" path="*.cshtml" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="vbhtm-ISAPI-4.0_32bit" path="*.vbhtm" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="vbhtml-ISAPI-4.0_32bit" path="*.vbhtml" verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="TRACEVerbHandler" path="*" verb="TRACE" type="" modules="ProtocolSupportModule" scriptProcessor="" resourceType="Unspecified" requireAccess="None" allowPathInfo="false" preCondition="" responseBufferLimit="4194304" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG" type="" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG" type="System.Web.Handlers.TransferRequestHandler" modules="ManagedPipelineHandler" scriptProcessor="" resourceType="Unspecified" requireAccess="Script" allowPathInfo="false"
  preCondition="integratedMode,runtimeVersionv4.0" responseBufferLimit="0" />
  <add name="StaticFile" path="*" verb="*" type="" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" scriptProcessor="" resourceType="Either" requireAccess="Read" allowPathInfo="false" preCondition="" responseBufferLimit="4194304"
  />
</handlers>

第二种方式是响应 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")
    
        HttpContext.Current.Response.AddHeader("Access-Control-Request-Method", "GET ,POST, PUT, DELETE");

        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin,Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "86400"); // 24 hours
        HttpContext.Current.Response.End();
    

【讨论】:

【参考方案8】:

我的解决方案是添加:

<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule"/>
    </modules>
</system.webServer>

到我的 web.config

【讨论】:

【参考方案9】:

这些答案中没有提到的一件事是,如果您使用的是 IIS,并且有带有自己单独 web.config 的子应用程序,您可能需要在包含以下代码的父目录中有一个 web.config。

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

【讨论】:

【参考方案10】:

Microsoft 花了数年时间来找出差距并发布带外 CORS 模块来解决这个问题。

    从Microsoft安装模块 Configure it 带 sn-ps

如下

<configuration>
    <system.webServer>
        <cors enabled="true" failUnlistedOrigins="true">            
            <add origin="http://*" allowed="true" />
        </cors>
    </system.webServer>
</configuration>

一般来说,它比您的自定义标头要容易得多,并且还可以更好地处理预检请求。

如果您对 IIS Express 也需要相同的内容,请使用 some PowerShell scripts I wrote。

【讨论】:

谢谢!使用 IIS CORS 模块是解决我的应用程序中的 CORS 问题的唯一方法。

以上是关于在 IIS7 上启用跨域资源共享的主要内容,如果未能解决你的问题,请参考以下文章

如何在连接到 API(在 Yii 中)的移动应用程序(cordova)上启用跨域资源共享

启用IIS7 gzip

在 IIS7 上使用 MVC3 时如何启用 gzip 压缩?

在 ASP.Net 5 / Core 中启用跨域资源共享 (CORS)

在使用 Swagger 开发的 NodeJS 上的 ExpressJS 框架中启用跨域资源共享 (CORS)

在启用 Windows 身份验证的情况下拒绝访问本地资源