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

Posted

技术标签:

【中文标题】使用 EnableCors 时“请求的资源不支持 http 方法 \'OPTIONS\'”【英文标题】:"The requested resource does not support http method 'OPTIONS'" when using EnableCors使用 EnableCors 时“请求的资源不支持 http 方法 'OPTIONS'” 【发布时间】:2018-01-19 05:23:23 【问题描述】:

我想在 Asp.net Web Api 中的一项特定操作上启用 CORS。以下是我的尝试:

[Route("api/mycontroller/myaction")]
[HttpPost]
[EnableCors("https://example.com", "*", "post")]
public async Task<IHttpActionResult> MyAction()

    ...

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

【问题讨论】:

嗯,您是否尝试过仅将请求作为 POST 而不是 OPTIONS 发送?我认为当您发出 CORS 请求时,浏览器会在后台为您执行 OPTIONS 内容(不过我可能弄错了)。 POST 请求本身可以工作,但是浏览器首先发送一个 OPTIONS 请求并且失败了,所以它永远不会发送 POST。 [EnableCors("example.com", "*", "post, options")]?告诉操作接受 OPTIONS 请求以及 POST 相同。如果我将 [HttpOptions] 注释与 [HttpPost] 一起添加,我不会收到错误消息,但它会尝试执行操作方法并需要授权。 EnableCors 应该响应 OPTIONS 请求。 【参考方案1】:

对我来说,我通过将以下代码添加到 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();
    

我不知道为什么会这样。 出于好奇,我尝试使用星号添加所有标头,但随后 Web API 抱怨缺少授权标头。

【讨论】:

你救了我的命 :) 我还需要将代码添加到 system.weserver 标签内的 web.config 文件中 &lt;httpProtocol&gt; &lt;customHeaders&gt; &lt;clear /&gt; &lt;add name="Access-Control-Allow-Origin" value="*" /&gt; &lt;add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" /&gt; &lt;add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /&gt; &lt;/customHeaders&gt; &lt;/httpProtocol&gt;【参考方案2】:

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

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

public static void Register(HttpConfiguration config)

    // New code
    config.EnableCors();

【讨论】:

我认为在 WebApiConfig.cs 中调用 config.EnableCors() 将为整个 API 启用 CORS。我没有意识到这是使用注释的先决条件。我也确实安装了 OWIN CORS,根据***.com/a/29452419/560722 将其删除【参考方案3】:

为确保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>

您可能还需要包括:

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

在IIS hijacks CORS Preflight OPTIONS request查看答案。

或者甚至只是这样:

 <add name="OPTIONSVerbHandler" path="*" verb="OPTIONS"
   modules="ProtocolSupportModule" requireAccess="None" />

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

if (filterContext.HttpContext.Request.HttpMethod == "OPTIONS")

    filterContext.HttpContext.Response.Flush();

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

if (Request.Headers.AllKeys.Contains("Origin", StringComparer.OridinalIgnoreCase)
    && Request.HttpMethod == "OPTIONS") 
    Response.Flush();

不管你用什么具体的代码来做,重点是:

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

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

public HttpResponseMessage Options()

    var response = new HttpResponseMessage
    
        StatusCode = HttpStatusCode.OK
    ;
    return response;

【讨论】:

感谢您提供非常全面的答案,我必须维护一个旧网站并且&lt;add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" /&gt; 有效。

以上是关于使用 EnableCors 时“请求的资源不支持 http 方法 'OPTIONS'”的主要内容,如果未能解决你的问题,请参考以下文章

请求的资源不支持 http 方法 'GET' 但使用 'POST'

ASP.NET Web API - 请求的资源不支持 http 方法“GET”

请求的资源不支持 http 方法 'OPTIONS'。?

请求的资源不支持 HTTP 方法“GET”

如何修复 - 请求的资源不支持 http 方法“POST”

TFS 评论“请求的资源不支持 http 方法 'POST'。”