2017-08-10 435 views
4

我想在Asp.net Web Api的一个特定操作中启用CORS。以下是我正在努力做到这一点:“使用EnableCors时,请求的资源不支持http方法'OPTIONS'”

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

但是,当我发送OPTIONS请求的路线,我回来了一个错误:“的请求的资源不支持HTTP方法‘选项’。”我也尝试删除[HttpPost]注释无济于事。 我错过了什么?

+0

嗯,你有没有试过只发送请求作为POST而不是OPTIONS?我想当你做CORS请求时,浏览器会在后台为你选择一些东西(尽管我可能会误会)。 – victor

+0

POST请求本身起作用,但浏览器首先发送OPTIONS请求并失败,所以它永远不会发送POST。 – SZH

+0

[EnableCors(“https://example.com”,“*”,“post,options”)]? 告诉操作接受OPTIONS请求以及POST – victor

回答

3

您可能错过了更高层次的电话HttpConfiguration.EnableCors,如下所述:https://enable-cors.org/server_aspnet.html

Add this code to your configuration:

public static void Register(HttpConfiguration config) 
{ 
    // New code 
    config.EnableCors(); 
} 
+0

我认为在WebApiConfig.cs中调用'config.EnableCors()'可以为整个API启用CORS。我没有意识到这是使用注释的先决条件。我也有安装OWIN CORS,我根据https://stackoverflow.com/a/29452419/560722 – SZH

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; 
} 
+0

删除,感谢非常全面的答案,我必须维护一个旧的网站和''有效。 –

+0

干杯 - 很高兴帮助 – sideshowbarker

1

对于我来说,我通过添加以下代码到Global.asax.cs中的的Application_BeginRequest功能添加下列头以请求 file:

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抱怨授权标题丢失。

相关问题