CORS 不适用于路由

Posted

技术标签:

【中文标题】CORS 不适用于路由【英文标题】:CORS not working with route 【发布时间】:2016-10-17 06:37:55 【问题描述】:

我的 Web api 上的端点有问题。我有一个 POST 方法不工作,原因是:

对预检请求的响应未通过访问控制检查:否 'Access-Control-Allow-Origin' 标头出现在请求的 资源。因此不允许使用原点“http://localhost:3000” 使用权。响应的 HTTP 状态代码为 405。

我不明白为什么这不起作用,因为我有很多方法确实适用于相同的 COSR 配置。唯一的区别是这个方法有一个指定的路由,如下所示:

// POST: api/Clave
        [EnableCors(origins: "*", headers: "*", methods: "*", SupportsCredentials = true)]
        [Route("id:int/clave")]
        [HttpPost]
        public HttpResponseMessage Post(int id, [FromBody]CambioClaveParameters parametros)
        
            UsuarioModel usuario = SQL.GetUsuario(id);

            if (Hash.CreateMD5(parametros.ViejaClave) != usuario.Clave.ToUpper())
            
                return Request.CreateResponse(HttpStatusCode.BadRequest);
            
            else if (Hash.CreateMD5(parametros.ViejaClave) == usuario.Clave.ToUpper())
            
                SQL.ModificarClaveUsuario(id, Hash.CreateMD5(parametros.NuevaClave));

                return Request.CreateResponse(HttpStatusCode.OK);
            
            else
            
                return Request.CreateResponse(HttpStatusCode.InternalServerError);
            
        

关于为什么会发生这种情况的任何想法?

谢谢!

【问题讨论】:

CORS 是否适用于 this 控制器中的其他方法? 我建议您使用prefix.io 来检查是否有问题。 【参考方案1】:

根据您消息中的“预检”一词,这是一个 OPTIONS 动词问题。如果您检查请求和响应,我相信您会看到直接在 POST 之前的请求是 OPTIONS 请求。 OPTIONS 请求询问服务器允许调用哪些方法。如果您尚未启用 OPTIONS 响应,或者您的 OPTIONS 响应不包含该 Uri 的 POST 方法,您将收到此响应。

这是描述该概念的链接(请参阅预检 CORS 请求部分) https://msdn.microsoft.com/en-us/magazine/dn532203.aspx

为了解决这种绕过 OPTIONS 设计的所有问题,您可以将与此类似的代码(不要成为***的程序员)添加到新模块或现有模块的 BeginRequest 方法中:

if (context.Request.HttpMethod.ToLower() == "options")

   var origin = context.Request.Headers["origin"];
   context.Response.StatusCode = 200;
   context.Response.AddHeader("Access-Control-Allow-Origin", origin);
   context.Response.AddHeader("Access-Control-Allow-Credentials", "true");
   context.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
   context.Response.End();

不过,理想情况下,您希望以编程方式确定请求是否有效,如果有效,则输出针对实际允许的内容定制的响应。

【讨论】:

我没有实现 BeginRequest... 我在哪里可以实现它?我正在看一些教程,但不清楚 感谢您让我找到解决此问题的方法...它无法正常工作...但现在错误不同了,我仍然收到 405 响应,但不再来自选项动词 您是否收到相同的消息 - “对预检检查的响应...”?如果是这样,问题继续存在于选项中;如果没有,@Federico 的答案是下一个去处。此外,如果您可以发布浏览器开发工具网络请求的 OPTIONS 和 POST 动词的净化输出以及响应标头,我可能会提供更多帮助。【参考方案2】:

希望你做得很好! 您可以使用下面的代码来允许对每个请求响应进行源访问。

 protected void Application_BeginRequest(object sender, EventArgs e)
        
   HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", *");

如需更多参考,您可以从以下链接获得帮助。 http://enable-cors.org/server_aspnet.html

【讨论】:

【参考方案3】:

您的 Web API 响应显然是 405,这表明您正在调用的 URI 不支持您的 HTTP 方法(在本例中为 POST)。

从这里开始,您需要了解为什么您的 URI 不支持POST。最可能的答案是您调用了错误的 URI。您收到 CORS 错误这一事实并不是问题的根源,而是源于您调用的错误 URI 未设置任何 Access-Control-Allow-Origin 标头。

查看您的控制器方法:

[EnableCors(origins: "*", headers: "*", methods: "*", SupportsCredentials = true)]
[Route("id:int/clave")]
[HttpPost]
public HttpResponseMessage Post(int id, [FromBody]CambioClaveParameters parametros)

在我看来,您正在使用 Route 属性,但没有在控制器类中设置 RoutePrefix 属性。

这意味着您的方法的正确 URI 如下:

http://localhost:xxxx/1/clave

不是,正如您所想的那样:

http://localhost:xxxx/api/Clave/1/clave

如果您想使用第二个 URI 访问您的资源,您需要在控制器中添加一个新的 RoutePrefix 属性:

[RoutePrefix("api/Clave")]
public class ClaveController : ApiController 
    //..

【讨论】:

我确实已经在控制器上配置了 RoutePrefix 属性......奇怪的是,如果我在本地使用 Postman 测试解决方案,它工作正常。问题在于 AJAX 调用 @NicoRiff 如果您随后使用相关控制器代码(包括 RoutePrefix)更新您的问题,并指定您从 AJAX 调用的 URI。【参考方案4】:

如果您使用 web api,只需在根级别创建一个类,将其命名为 Startup.cs 如果您可以尝试在启动时添加以下代码,看看是否有效。此代码将在您的应用程序管道中注入 cors middelware。您可能需要通过 nuget 添加 owin。试试看

[assembly: OwinStartup(typeof(MyProject.API.Startup))]

namespace MyProject.API

    public class Startup
    
        public void Configuration(IAppBuilder app)
        
            app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
            app.UseWebApi(WebApiConfig.Register());
        
     

【讨论】:

该类应该在哪里?我应该从哪里调用该函数?。 我没有使用 OWIN

以上是关于CORS 不适用于路由的主要内容,如果未能解决你的问题,请参考以下文章

CORS 标头不适用于 Express 云功能中的特定路由

WebAPI - 属性路由 POST 不适用于 WebAPI Cors?

Spring Security 保护路由 hasRole,hasAuthority 不适用于 CORS http 请求

为啥 Laravel 中间件适用于单个路由而不适用于一组路由

CORS 不适用于 .NET Core API 和 Angular 前端

Go Restful API:CORS 配置适用于 React 但不适用于 Angular