请求返回404 Not OPTIONS for OPTIONS,但在使用Postman(ASP.NET)时工作正常吗?

时间:2016-01-12 17:45:04

标签: asp.net api iis-7 cors iis-7.5

浏览器控制台输出:

  

XMLHttpRequest无法加载https://api.[...].com/[...]。回应   预检请求未通过访问控制检查:否   请求中存在“Access-Control-Allow-Origin”标头   资源。因此,不允许原点“http://localhost”访问。   响应的HTTP状态代码为404.

我有一个AngularJS应用程序正在调用ASP.NET内置的API。最近,后端团队将版本控制添加到应用程序中,由于某种原因,其中一个API端点将不再为OPTIONS请求返回200 OK(即使同一服务器上的所有其他API端点仍然返回200 OK)。始终返回 404 Not Found

ASP.NET服务器似乎正在使用WebApi.Cors包;没有声明特定的[HttpOptions]方法(所有OPTIONS请求都是通过包处理的);并且web.config使用*为所有原点,标题和方法提供CorsConfig。

我已尝试过Google搜索结果中的许多解决方案,但没有任何效果。

任何人都面临类似的问题,可以就可能导致问题的原因提供一般性指导,或者如何对问题进行潜在测试,或尝试解决方案?

[编辑:]找到解决方案。

由于在该特定路由上删除了API端点的“版本1”而导致的问题。该端点上的第一个有效版本现在是“版本2”。所以我添加了一个空白的Controller方法来捕获“Version 1”的请求(只返回一个空字符串,仅此而已),这足以让OPTION请求解析。

2 个答案:

答案 0 :(得分:2)

我认为这里的部分问题是路由已经改变:

  

最近,后端团队为应用程序添加了版本控制

要检查的事项:

  1. WebApi配置
  2. 您是否可以确保您的配置是Global.asax文件中的第一项:

    void Application_Start(object sender, EventArgs e)
    {
         GlobalConfiguration.Configure(WebApiConfig.Register);
         //...
    }
    
    1. Web API路由
    2. 是否在WebApiConfig中正确配置了版本?

      public static void Register(HttpConfiguration config)
      {
           config.EnableCors(new EnableCorsAttribute("*", "*", "*");
      
           config.Routes.MapHttpRoute(
               name: "DefaultApi",
               routeTemplate: "api/v2/{controller}/{id}",
               defaults: new { id = RouteParameter.Optional }
      }
      

      在IIS 7.5中,我使用CORS的唯一方法是通过web.config而不是通过Nuget包:

      我的web.config如下:                                                                                                                                                             

            <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="*" modules="IsapiModule" scriptProcessor="%windir%\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="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
            <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
          </handlers>
      </system.webServer>
      

答案 1 :(得分:-1)

找到解决方案。在这里发布给未来有问题的其他人。

API端点以&#34;版本2和#34;开头。之前有一个版本1&#34;它从未进入生产阶段,但由于签名将完全改变而被删除/停止。之所以这样做是因为开发团队一直在使用&#34;版本1&#34;到目前为止,但由于它没有投入生产,逻辑决定不再拥有该版本/端点。

出于某种原因,没有&#34;版本1&#34;导致OPTIONS失败并返回404 Not Found。我的猜测是因为OPTIONS飞行前请求实际上并未包含所需的版本标头,因此它永远不会解析为Controller中的GET目的地。

因此,必须具有版本1 引用,即使它是一个只返回空字符串的占位符。

在:

[VersionedRoute("products", 2, Name = "GetProducts")]
[HttpGet]
public IHttpActionResult GetProducts([FromUri] GetProductsRequest request)
{

后:

[VersionedRoute("products", 1, Name = "GetProducts")]
[HttpGet]
public IHttpActionResult GetProducts()
{
    return NotFound();
}

[VersionedRoute("products", 2, Name = "GetProducts_V2")]
[HttpGet]
public IHttpActionResult GetProducts_V2([FromUri] GetProductsRequest request)
{