CORS无法使用路由

时间:2016-06-15 23:21:48

标签: c# asp.net asp.net-web-api cors

我的网络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);
            }
        }

为什么会发生这种情况?

谢谢!

4 个答案:

答案 0 :(得分:5)

根据您的讯息中的“预检”一词,这是一个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();
}

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

答案 1 :(得分:3)

如果您正在使用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());
        }
     }
}

答案 2 :(得分:3)

您的Web API响应显然是405,表示您正在调用不支持HTTP方法的URI(在本例中为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访问资源,则需要在Controller中添加新的RoutePrefix属性:

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

答案 3 :(得分:3)

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

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

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