"使用EnableCors时,请求的资源不支持http方法'OPTIONS'"

SZH*_*SZH 7 c# cors asp.net-web-api

我想在Asp.net Web Api中的一个特定操作上启用CORS.这是我试图这样做的方式:

[Route("api/mycontroller/myaction")]
[HttpPost]
[EnableCors("https://example.com", "*", "post")]
public async Task<IHttpActionResult> MyAction()
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是当我向路由发送OPTIONS请求时,我收到一个错误:"请求的资源不支持http方法'OPTIONS'." 我也尝试删除[HttpPost]注释无济于事.我错过了什么?

Cia*_*her 7

对我来说,我通过将以下代码添加到Global.asax.cs文件的Application_BeginRequest函数中,将以下标头添加到请求中:

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin", StringComparer.CurrentCultureIgnoreCase)
        && Request.HttpMethod == "OPTIONS")
    {
        Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Pragma, Cache-Control, Authorization ");
        Response.End();
    }
}
Run Code Online (Sandbox Code Playgroud)

我不知道为什么会这样.出于好奇,我尝试使用星号添加所有标题,但随后Web API抱怨Authorization标头丢失.


Kir*_*kin 5

您可能错过了对的更高级别调用HttpConfiguration.EnableCors,如下所述:https : //enable-cors.org/server_aspnet.html

将此代码添加到您的配置中:

public static void Register(HttpConfiguration config)
{
    // New code
    config.EnableCors();
}
Run Code Online (Sandbox Code Playgroud)


sid*_*ker 5

为确保OPTIONS请求在到达应用程序代码之前由您的应用程序代码而不是系统的其他部分处理,您可以尝试将以下内容添加到您的web.config

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <remove name="TRACEVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

您可能还需要包括:

<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS"
  modules="IsapiModule" requireAccess="None"
  scriptProcessor="C:\Windows\System32\inetsrv\asp.dll"
  resourceType="Unspecified" />
Run Code Online (Sandbox Code Playgroud)

请参阅IIS劫持CORS Preflight OPTIONS请求中的答案。

甚至就是这样:

 <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS"
   modules="ProtocolSupportModule" requireAccess="None" />
Run Code Online (Sandbox Code Playgroud)

如果这些都不起作用,那么可以在您的global.asax代码或其他代码中尝试:

if (filterContext.HttpContext.Request.HttpMethod == "OPTIONS")
{
    filterContext.HttpContext.Response.Flush();
}
Run Code Online (Sandbox Code Playgroud)

…或其他一些变化,例如:

if (Request.Headers.AllKeys.Contains("Origin", StringComparer.OridinalIgnoreCase)
    && Request.HttpMethod == "OPTIONS") {
    Response.Flush();
}
Run Code Online (Sandbox Code Playgroud)

不管您使用什么特定的代码来实现,关键是:

  • 确保OPTIONS在到达应用程序代码之前,请求实际上已被您的应用程序代码捕获/处理,而不是被系统的其他部分捕获/处理。
  • 确保您对OPTIONS应用程序代码中的请求有明确的处理
  • OPTIONS在您的应用程序代码中进行处理Response.Flush()

或者,我不确定另一种方法是否与您所编码的情况有关,但我以防万一:

public HttpResponseMessage Options()
{
    var response = new HttpResponseMessage
    {
        StatusCode = HttpStatusCode.OK
    };
    return response;
}
Run Code Online (Sandbox Code Playgroud)