在IIS7上启用跨域资源共享

100

最近我遇到了向另一个域名发送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>

enter image description here

目前一切都正常,但在返回有效的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。 - Iman
11个回答

82

很可能是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();
        }

    }

4
我尝试了两种方法,但只有BeginRequest方法对我有效。谢谢@Shah。 - Basant B. Pandey
对我来说,以与 OP 相同的方式将其添加到 web.config 中是唯一的方法。Global.asax/BeginRequest 不起作用。 - twDuke
5
经过2天的研究,我发现基于 Application_BeginRequest 的替代解决方案是我修复问题的唯一方法。我试过其他方法,包括使用 customHeaders(https://dev59.com/GXfZa4cB1Zd3GeqPOzQI#19091291)、移除 OPTIONSVerbHandler 处理程序、移除 WebDAV 模块和处理程序(http://stackoverflow.com/a/20705500/827168),但都无法解决我的问题。希望这能帮助其他人。感谢 @Mendhak 提供的答案! - pomeh
32
该死的ASP.NET和IIS,为什么配置一个简单的CORS概念会这么难?实际上很简单,只需要阅读W3C的规范,你可以在10分钟内学会它,但是你需要花费10天时间去弄清楚如何在ASP.NET和IIS中进行配置。 - Saeed Neamati
3
@Mendhak,你救了我的命哈哈。我添加的唯一一件事就是始终使用HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");,因为共享认证cookie。 - Nexxas
显示剩余7条评论

29

我无法发表评论,所以不得不将这个问题放在一个单独的答案中,但它与Shah所接受的答案相关。

最初我按照Shah的答案进行了配置(谢谢!),通过重新配置IIS中的OPTIONSVerbHandler,但是当我重新部署应用程序时,我的设置被还原了。

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

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

21
对于不经常使用web.config的人来说,这个内容应该放在"<system.webServer>"标签内。 - SemanticZen
这个答案对我在部署在IIS7下的MVC6 Web API项目中有所帮助。在生产环境中,这个选项很好用,但是如上所建议,在迁移到其他终端时,我不得不删除同一项目中的它!谢谢。 - sanpat

29

我发现在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中添加了以下内容,然后将OPTIONSVerbHandler移动到IIS 7 “handler mappings”列表的顶部。 我还通过双击处理程序映射部分中的处理程序,然后单击“请求限制”,再单击访问选项卡来授予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另一个请求,这时就正确了。 - Marshal
看起来当前版本的Chrome不再考虑在响应中收到的CORS头,如果出现错误的HTTP状态。因此,在这种情况下,它将不再继续执行跨域请求。在我看来,这是更好的行为。 - Frédéric
1
感谢您的回复。如果您在上面的回复中匆忙地阅读了,不要忘记按照上面的说明给予 OPTIONSVerbHander 读取权限。 - John Meyer
更安全的做法是指定来源。 看一下: <add name="Access-Control-Allow-Origin" value="http://my.origin.host" /> - Gabriel Simas

12

从DavidG的答案(链接:/a/16229340/1178314)中详细阐述了基本解决方案所需的步骤:

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

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

    您还可以在web.config中完成此操作,方法是在<system.webServer><handlers>下重新定义所有处理程序(<clear>然后<add ...>再添加回来,这就是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>
    

    你也可以在IIS控制台中完成这个操作。

这是一种基本的解决方案,因为它甚至会在不需要cors头文件的请求上发送。但是对于WCF来说,它似乎是最简单的方法。

对于MVC或Web API,我们可以通过代码(手动或使用Web API最新版本中提供的内置支持)来处理OPTIONS动词和cors头文件。


这对我有用。我不喜欢每个处理程序最终都在Web.config中重新定义,但不幸的是似乎这是我需要做的,以使我们的WCF服务启用CORS。+1 - Manny

11

微软花了多年时间才找出其中的漏洞并发布了一个独立的CORS模块来解决这个问题。

  1. Microsoft安装该模块
  2. 使用下面的片段进行配置

如下所示:

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

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

如果您需要IIS Express的相同功能,请使用我编写的一些PowerShell脚本。

https://github.com/lextm/iisexpress-cors


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

9
405响应是“方法不被允许”的响应。看起来您的服务器没有正确配置以处理CORS预检请求。您需要执行两个操作:
1)启用IIS7响应HTTP OPTIONS请求。您收到405是因为IIS7拒绝了OPTIONS请求。我不知道如何做这件事,因为我不熟悉IIS7,但Stack Overflow上可能有其他人可以帮忙。
2)配置应用程序以响应CORS预检请求。您可以通过在部分下添加以下两行来完成此操作: 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/


3
我的解决方案是添加以下内容:
<system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule"/>
    </modules>
</system.webServer>

对我的web.config文件


3
使用ASP.NET Web API 2,通过NuGet安装Microsoft ASP.NET跨域支持。

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);
}

你知道是否有任何“编程方式”可以设置EnableCorsAttribute的第一个“ORIGIN”参数吗?假设不是在注册表中,而是针对每个进来的HTTP请求。检测它来自哪里,确保它是OK的(根据一些批准的列表进行检查),然后返回一个带有Access-Allow-Control-Origin="thatdomain.com"的响应?@Andrew - Mark Pieszak - Trilon.io

3

你好。

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

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();
    }
}

2

这些答案中没有提到的一件事是,如果您正在使用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>

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