2013-06-27 15 views
28

Sto inviando una richiesta di posta a un'applicazione di servizio WCF RESTFUL. Sono in grado di inviare con successo una richiesta POST tramite Fiddler.jQuery .ajax() Richiesta POST genera 405 (metodo non consentito) su RESTful WCF

Tuttavia quando faccio questo attraverso il metodo di jQuery Ajax la funzione restituisce il seguente al Chrome Console per gli sviluppatori:

OPTIONS http://www.example.com/testservice/service1.svc/GetData 405 (Method Not Allowed) jquery.min.js:6 

Ma poi un secondo dopo i registri:

Object {d: "You entered 10"} testpost.html:16 

Che cosa questo mi dice è che jQuery sta inviando una richiesta OPTIONS, che non riesce e quindi invia una richiesta POST che restituisce i dati previsti.

mio codice jQuery:

$.ajax() {   
type: "POST", //GET or POST or PUT or DELETE verb 
    url: "http://www.example.com/testservice/service1.svc/GetData", // Location of the service  
    data: '{"value":"10"}', //Data sent to server 
    contentType:"application/json", 
    dataType: "json", //Expected data format from server  
    processdata: false, 
    success: function (msg) {//On Successfull service call 
     console.log(msg); 
    }, 
    error: function (xhr) { console.log(xhr.responseText); } // When Service call fails    
}); 

Sto usando jQuery versione 2.0.2.

Qualsiasi aiuto sul motivo per cui questo errore si sta verificando sarebbe di grande aiuto.

risposta

54

Il tuo codice sta attualmente tentando di effettuare una richiesta Cross-domain (CORS), non un ordinario POST.

Ovvero: i browser moderni consentiranno solo le chiamate Ajax ai servizi nello stesso dominio come pagina HTML.

Esempio: Una pagina in http://www.example.com/myPage.html può richiedere direttamente solo i servizi che sono http://www.example.com, come http://www.example.com/testservice/etc. Se il servizio è in un altro dominio, il browser non effettuerà la chiamata diretta (come ci si aspetterebbe). Invece, proverà a fare una richiesta CORS.

Per dirla in breve, per eseguire una richiesta CORS, il browser:

  • dapprima inviare una OPTION richiesta all'URL di destinazione
  • E poi solo se la risposta del server che OPTION contiene il adequate headers (Access-Control-Allow-Origin is one of them) per consentire la richiesta CORS, il browse eseguirà la chiamata (quasi esattamente come se la pagina HTML fosse nello stesso dominio).
    • Se le intestazioni previste non arrivano, il browser si arrende semplicemente (come ha fatto a te).

Come risolverlo? Il modo più semplice è abilitare CORS (abilitare le intestazioni necessarie) sul server.

Se non si dispone dell'accesso dal lato server, è possibile eseguire il mirror del servizio Web da qualche altra parte, quindi abilitare CORS in tale posizione.

+0

Va bene ha senso ora. Grazie mille. –

+0

would't 'jsonp' fa anche il lavoro - purché sia ​​supportato dal server? – ProblemsOfSumit

+0

@Sumit Se tutto ciò che fai è 'GET', allora ** JSONP ** potrebbe essere un'opzione. Tuttavia, JSONP è più una soluzione alternativa che una soluzione, dal momento che puoi fare cose molto limitate con esso. Non puoi fare 'POST's (o' PUT's ecc.) Tramite JSONP. – acdcjunior

3

È anche possibile creare le intestazioni richieste in un filtro.

@WebFilter(urlPatterns="/rest/*") 
public class AllowAccessFilter implements Filter { 
    @Override 
    public void doFilter(ServletRequest sRequest, ServletResponse sResponse, FilterChain chain) throws IOException, ServletException { 
     System.out.println("in AllowAccessFilter.doFilter"); 
     HttpServletRequest request = (HttpServletRequest)sRequest; 
     HttpServletResponse response = (HttpServletResponse)sResponse; 
     response.setHeader("Access-Control-Allow-Origin", "*"); 
     response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT"); 
     response.setHeader("Access-Control-Allow-Headers", "Content-Type"); 
     chain.doFilter(request, response); 
    } 
    ... 
} 
+2

Non è questo Java? – jonayreyes

4

È necessario aggiungere questo codice in global.aspx:

protected void Application_BeginRequest(object sender, EventArgs e) 
     { 
      HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); 
      if (HttpContext.Current.Request.HttpMethod == "OPTIONS") 
      { 
       HttpContext.Current.Response.AddHeader("Cache-Control", "no-cache"); 
       HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST"); 
       HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept"); 
       HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000"); 
       HttpContext.Current.Response.End(); 
      } 
     } 
Problemi correlati