为什么在使用Origin报头时找不到路由?



我的WebAPI 2.1服务在请求OPTIONS/project/{id}时返回404 "route not found"错误我正在使用基于属性的路由。

使用CuRL,我发现当我去掉Origin头时,请求成功。

我已经启用了CORS,像这样设置我的控制器:

[RoutePrefix("project")]
public class ProjectController : ApiController
{
    protected ProjectRepo Repo;
    public ProjectController()
    {
        if (System.Web.HttpContext.Current.Request.HttpMethod == HttpMethod.Options.ToString())
            return;
        Repo = new ProjectRepo();
    }
    [Route("{id?}")]
    public HttpResponseMessage Options(int? id = null)
    {
        return new HttpResponseMessage { StatusCode = HttpStatusCode.OK };
    }
}

网络。配置设置为允许所有起源:

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="GET, OPTIONS, PUT, POST, DELETE, HEAD" />
    <add name="Access-Control-Allow-Headers" value="Accept, Authorization, Origin, Content-Type, X-Requested-With" />
    <add name="Access-Control-Expose-Headers" value="Accept, Origin, Content-Type, X-Requested-With" />
  </customHeaders>
</httpProtocol>

第一个CuRL请求失败并返回404,但是当我删除Origin标头后,下一个请求成功。

1。

$ curl -v -H "Origin: http://localhost:51696/project/1" 
-H "Access-Control-Request-Method: DELETE" -X OPTIONS 
http://localhost:51696/project/1
* Adding handle: conn: 0x4c3378
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x4c3378) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 51696 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 51696 (#0)
> OPTIONS /project/1 HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:51696
> Accept: */*
> Origin: http://localhost:51696/project/1
> Access-Control-Request-Method: DELETE
>
< HTTP/1.1 404 Not Found
< Cache-Control: no-cache
< Pragma: no-cache
< Content-Type: application/json; charset=utf-8
< Expires: -1
* Server Microsoft-IIS/8.0 is not blacklisted
< Server: Microsoft-IIS/8.0
< X-AspNet-Version: 4.0.30319
< X-SourceFiles: =?UTF-8?B?YzpccHJvamVjdHNcYW5hbHl0aWNzXENvbVNlcnZpY2VcQ29tU2VydmljZVxwcm9qZWN0XDE=?=
< X-Powered-By: ASP.NET
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, OPTIONS, PUT, POST, DELETE, HEAD
< Access-Control-Allow-Headers: Accept, Authorization, Origin, Content-Type, X-Requested-With, X-360i-Authorization
< Access-Control-Expose-Headers: Accept, Origin, Content-Type, X-Requested-With, X-360i-Authorization
< Date: Mon, 19 May 2014 16:29:45 GMT
< Content-Length: 197
<
{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:51696/project/1'.","MessageDetail":"No action was found on the controller
'Project' that matches the request."}* Connection #0 to host localhost left intact

2。没有Origin头的CuRL请求返回200 OK:

$ curl -v -H "Access-Control-Request-Method: DELETE" -X OPTIONS 
http://localhost:51696/project/1
* Adding handle: conn: 0x1d63238
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x1d63238) send_pipe: 1, recv_pipe: 0
* About to connect() to localhost port 51696 (#0)
*   Trying ::1...
* Connected to localhost (::1) port 51696 (#0)
> OPTIONS /project/1 HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:51696
> Accept: */*
> Access-Control-Request-Method: DELETE
>
< HTTP/1.1 200 OK
< Cache-Control: no-cache
< Pragma: no-cache
< Expires: -1
* Server Microsoft-IIS/8.0 is not blacklisted
< Server: Microsoft-IIS/8.0
< X-AspNet-Version: 4.0.30319
< X-SourceFiles: =?UTF-8?B?YzpccHJvamVjdHNcYW5hbHl0aWNzXENvbVNlcnZpY2VcQ29tU2VydmljZVxwcm9qZWN0XDE=?=
< X-Powered-By: ASP.NET
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Methods: GET, OPTIONS, PUT, POST, DELETE, HEAD
< Access-Control-Allow-Headers: Accept, Authorization, Origin, Content-Type, X-Requested-With, X-360i-Authorization
< Access-Control-Expose-Headers: Accept, Origin, Content-Type, X-Requested-With, X-360i-Authorization
< Date: Mon, 19 May 2014 16:29:03 GMT
< Content-Length: 0
<
* Connection #0 to host localhost left intact

我对这一切都很陌生,所以你可能已经想到了下面的内容,但是,由于你的问题不清楚,我想我应该提一下。

如何启用CORS?你可以按控制器,按动作或全局来做。看看你问题中的控制器代码,我看不到你的控制器或任何动作的任何[EnableCors(...)]属性,所以也许你是在全局上这样做的?如果是,您是否使用了EnableCorsAttribute实例:

var cors = new EnableCorsAttribute("www.example.com", "*", "*");
config.EnableCors(cors);

还是你刚刚做了:

config.EnableCors();

它本身是不够的?

像这样启用CORS后,它可以工作:

var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);

并注释了web.config中的大部分Access-Control-*头:

  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <!--  enable CorsAttribute explicitly in WebApiConfig.cs
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Methods" value="GET, HEAD, POST, PUT, DELETE, OPTIONS" />
        <add name="Access-Control-Allow-Headers" value="Accept, Content-Type, Origin, Authorization, X-Requested-With, X-360i-Authorization" />
        -->
        <add name="Access-Control-Expose-Headers" value="Accept, Origin, Content-Type, X-Requested-With, X-360i-Authorization" />
      </customHeaders>
    </httpProtocol>

最新更新