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

Posted

技术标签:

【中文标题】请求的资源不支持 http 方法 \'OPTIONS\'。?【英文标题】:The requested resource does not support http method 'OPTIONS'.?请求的资源不支持 http 方法 'OPTIONS'。? 【发布时间】:2014-08-12 16:50:55 【问题描述】:

我正在从我的 angular.js 客户端向 asp.net web api PUT 方法发出以下请求:

var org = 
                  OrgId: 111,
                  name: 'testing testing'
          ;
$http.put("http://localhost:54822/api/data/putorganisation/1/", org).then(function(status) 
         console.log("success PUT");
         return status.data;
);

但是得到以下错误消息(在提琴手中):

"message":"The requested resource does not support http method 'OPTIONS'."

这是我的 asp.net web api web.config 文件的一部分:

 <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type,x-xsrf-token,X-Requested-With" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
      </customHeaders>
    </httpProtocol>
    <validation validateIntegratedModeConfiguration="false" />
    <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" />
      <remove name="WebDAV" />
    </handlers>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
    </modules>
  </system.webServer>

数据控制器 web api:

public HttpResponseMessage Options()

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


public HttpResponseMessage PutOrganisation(int id, [FromBody]Organisation org)

  var opStatus = _Repository.UpdateOrganisation(org);
  if (opStatus.Status)
  
     return Request.CreateResponse<Organisation>(HttpStatusCode.Accepted, org);
  

return Request.CreateErrorResponse(HttpStatusCode.NotModified, opStatus.ExceptionMessage);

这是我的问题:为什么我在提琴手(有效)中发出与 angularclient(无效)完全相同的请求时会收到错误消息(见上文)??

【问题讨论】:

【参考方案1】:

我知道这是一个老问题,但我遇到了同样的问题,并认为我可以帮助其他试图弄清楚的人。

我通过删除 Web.config 中的 2 个处理程序配置解决了这个问题:

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

我不知道它解决问题的确切原因,但我的工作理论是&lt;remove name="OPTIONSVerbHandler" /&gt; 默认情况下禁止 OPTIONS 请求。从浏览器发送请求时,它会在 PUT 请求之前先发送一个 OPTIONS 请求,因此它永远不会到达 PUT 请求,因为第一个 OPTIONS 请求被拒绝为 api 上的无效 http 方法。

在提琴手中,我假设它只发送 PUT 请求(我观察到使用 Postman Web 应用手动发送请求的相同行为)。所以它跳过了禁止的 OPTIONS 请求并成功。

【讨论】:

非常感谢,拯救我的一天!试着让 CORS 正常工作。 M$ 确实需要更新文档和项目模板,我只需更改 web.config 就可以进行修复。 &lt;customHeaders&gt; &lt;add name="Access-Control-Allow-Credentials" value="true"/&gt; &lt;add name="Access-Control-Allow-Origin" value="http://appdomain.com" /&gt; &lt;add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" /&gt; &lt;add name="Access-Control-Allow-Headers" value="Content-Type" /&gt; &lt;/customHeaders&gt; 通过删除这个,我得到 404 而不是 400 根据您购买删除 OPTIONSVerbHandler 的工作理论,我们删除了处理 OPTIONS 动词的处理程序,我只是从我的 web.config 中删除了该行。之后它起作用了。您对为什么还需要删除 有任何理论吗? 只评论 &lt;!--&lt;remove name="OPTIONSVerbHandler" /&gt;--&gt; 为 ne 做的 @NathanHanna 你是山羊,我已经为此苦苦挣扎了好几个星期,这解决了它。谢谢。【参考方案2】:

我也遇到了同样的问题,经过一番研究,我对 web.config 和 Global.asax.cs 文件进行了以下更改

<configuration>

  <system.webServer>
    <directoryBrowse enabled="true" />
    <validation validateIntegratedModeConfiguration="false" />
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, PATCH, DELETE, OPTIONS" />
        <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept" />

      </customHeaders>
    </httpProtocol>
    <handlers>
      <remove name="WebDAV" />
      <remove name="OPTIONSVerbHandler"/>
      <remove name="TRACEVerbHandler" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
      <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
      <remove name="ExtensionlessUrlHandler-Integrated-4.0" />

      <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="C:\windows\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="C:\windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
      <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
    </handlers>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="WebDAVModule" />
      <remove name="ApplicationInsightsWebTracking" />
      <add name="ApplicationInsightsWebTracking" type="Microsoft.ApplicationInsights.Web.ApplicationInsightsHttpModule, Microsoft.AI.Web" preCondition="managedHandler" />
    </modules>
  </system.webServer>

</configuration>

添加以下代码 global.ascx.cs

protected void Application_BeginRequest()

    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS");
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    

【讨论】:

【参考方案3】:

这几乎肯定是一个 CORS 问题。我首先要read up about it 确保您了解这是什么以及为什么它很重要。而且我猜你的服务器配置不正确。

不幸的是,我对 .net 了解不多,但这个CORS tutorial for .net 非常清楚地描述了你应该做什么。

您似乎缺少EnableCors 注释。看起来您需要在控制器中添加类似 [EnableCors("*", "*", "*")] 的内容。不需要显式处理 OPTIONS。当然,在生产中,您不想使用通配符来处理 CORS。它们应该更具体,但这对于测试来说很好。

【讨论】:

【参考方案4】:

Andrew 是正确的,这很可能是 CORS 问题。您需要将 EnableCors 属性添加到您的 Controller 类中,这样看起来就像这样

 [EnableCors(origins: "https://example.com,http://example.org", headers: "*", methods: "*")]
    public class  TestController : ApiController
    
         // your code 

stack overflow post 中提到了另一种方法

【讨论】:

【参考方案5】:

是的,一个老歌,但一个好人。我有同样的问题和症状,但我的决心是自己造成的。无论如何我都会分享它。我们的服务在启动时配置所有MapHttpRoute 调用中使用的控制器的方式包括[DisableCors] 属性。一旦我重新配置本地机器启动以使用不同的控制器,一切正常。因此,如果您已经完成了此处列出的所有其他操作,请检查您的控制器并确保您没有像我那样做一些愚蠢的事情。

【讨论】:

【参考方案6】:

显然,在某些情况下,OPTIONS 请求会在“真实”请求之前发送,以确定真实请求是否可以安全发送,因为 CORS。请参阅以下 MS 文章:http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api 并搜索“预检请求”。

以下一些问答可能也有帮助:

jQuery $.ajax(), $.post sending "OPTIONS" as REQUEST_METHOD in Firefox AJAX in Chrome sending OPTIONS instead of GET/POST/PUT/DELETE? Why does this jQuery AJAX PUT work in Chrome but not FF How to support HTTP OPTIONS verb in ASP.NET MVC/WebAPI application

【讨论】:

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

HTTP/1.1协议支持的8种请求方法

http请求方法

http请求方法

HTTP请求方法

HTTP中的OPTIONS请求

mini web