2016-06-15 15 views
9

Mam problem z punktem końcowym w moim interfejsie internetowym. Mam metodę POST, który nie działa z powodu:CORS nie działa z trasą

odpowiedź do prefligtu żądanie nie przechodzi kontrolę kontroli dostępu: Nie „Access-Control-Allow-Origin” header jest obecny na wymaganym zasobu. Pochodzenie "http://localhost:3000" jest zatem niedozwolone pod warunkiem dostępu . Odpowiedź miała kod stanu HTTP 405.

Nie widzę powodu, dla którego to nie działa, ponieważ mam wiele metod, które rzeczywiście działają z tą samą konfiguracją COSR. Jedyna różnica polega na tym, że ta metoda ma określoną trasę, jak widać poniżej:

// 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); 
      } 
     } 

Jakieś pomysły, dlaczego tak się dzieje ?.

Dzięki !.

+1

Czy CORS działa na inne metody w * tym * kontrolerze? – mayu

+0

tak działa – NicoRiff

+0

Polecam użycie http://www.prefix.io/ do sprawdzenia, czy coś jest nie tak. – Shago

Odpowiedz

4

W oparciu o słowo "preflight" w wiadomości, jest to problem z wersją OPCJE. Jeśli przeanalizujesz prośby i odpowiedzi, uważam, że zobaczysz, że żądanie bezpośrednio przed POST jest żądaniem OPCJI. Żądanie OPTIONS pyta serwer, jakie metody mogą być wywołane. Jeśli nie włączono opcji OPCJE lub odpowiedź OPCJE nie zawiera metody POST dla tego URI, otrzymasz odpowiedź.

Oto link opisując koncepcję (patrz punkt Preflight CORS kupna) https://msdn.microsoft.com/en-us/magazine/dn532203.aspx

Aby wyjaśnić tego pominięciem OPCJI wszystko jest zaprojektowane do zrobienia, można dodać kod podobny do tego (nie być programista cargo-kult) do BeginRequest metody nowego lub istniejącego modułu:

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(); 
} 

Idealnie, choć byś chciał programowo określić, czy wniosek jest poprawny, a jeśli tak, to wyjście odpowiedzią dostosowane do tego, co jest actuall Y dozwolone.

+0

Nie zaimplementowałem BeginRequest ... gdzie mogę go zaimplementować ?. Patrzę na kilka tutoriali, ale nie są one jasne. – NicoRiff

+0

Znalazłem to ... nieważne ... dzięki! – NicoRiff

+0

Dzięki za doprowadzenie mnie do ścieżki rozwiązania tego problemu ... To nie działa ... ale teraz błędy są różne, nadal otrzymuję odpowiedź 405, ale nie więcej z OPCJI czasownika – NicoRiff

3

jeśli korzystasz z interfejsu API po prostu utwórz jedną klasę na poziomie root nazwa to Startup.cs Jeśli możesz spróbować dodać następujący kod w swoim starcie i sprawdzić, czy to działa. Ten kod wprowadzi cors middelware do pip pot application. Prawdopodobnie musisz dodać owin przez nuget. Spróbować

[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()); 
     } 
    } 
} 
+0

gdzie ma być ta klasa ?. Skąd mam wezwać tę funkcję ?. – NicoRiff

+0

zaktualizowałem moją odpowiedź –

+0

Nie używam OWIN – NicoRiff

3

odpowiedź Web API jest wyraźnie 405, co wskazuje, że dzwonisz URI, który nie obsługuje metodę HTTP (w tym przypadku POST).

Zaczynając od tego, musisz zrozumieć dlaczego Twój URI nie obsługuje POST. Najbardziej prawdopodobną odpowiedzią jest to, że wywołujesz nieprawidłowy identyfikator URI. Fakt, że otrzymujesz błąd CORS, nie jest źródłem problemu i wynika z faktu, że błędny identyfikator URI, do którego dzwonisz, nie ustawia żadnego nagłówka Access-Control-Allow-Origin.

Patrząc na metodzie kontrolera:

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

Wydaje mi się, że używasz atrybut Route, ale nie ustawiając atrybut w swojej klasie kontrolera RoutePrefix.

To oznacza, że ​​prawidłowy URI dla metody jest następujący:

http://localhost:xxxx/1/clave 

I nie, jak mogłoby się wydawać, że jedno:

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

Jeśli chcesz uzyskać dostęp do Twój zasób używa drugiego identyfikatora URI, który musisz umieścić w swoim kontrolerze nowego atrybutu RoutePrefix:

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

Mam skonfigurowane atrybuty RoutePrefix na kontrolerze ... Dziwne jest to, że jeśli testuję rozwiązanie za pomocą Postmana lokalnie, to działa dobrze. Problem polega na tym, że AJAX wywołuje – NicoRiff

+0

@NicoRiff, jeśli następnie zaktualizowałeś swoje pytanie odpowiednim kodem kontrolera (włączyłeś RoutePrefix), a także określisz, który jest identyfikatorem URI, który wywołujesz z AJAX. –

3

Mam nadzieję, że robisz dobrze! możesz użyć poniższego kodu, który umożliwi dostęp do źródła przy każdej odpowiedzi na żądanie.

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

po więcej informacji można uzyskać pomoc pod poniższym linkiem. http://enable-cors.org/server_aspnet.html

Powiązane problemy