jQuery.ajax () lancer de requête POST 405 (Méthode non autorisée) sur la WCF RESTful

j'envoie une demande postale à une application de service RESTFUL WCF. Je suis en mesure de réussir à envoyer un POST demande par le biais de Violoneux.

cependant quand je fais ceci par la méthode Ajax de jQuery la fonction renvoie ce qui suit à la Console de développement Chrome:

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

mais ensuite une seconde après logs:

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

ce que cela me dit est que jQuery envoie un OPTIONS demande, qui ne parvient pas, puis l'envoi d'un POST requête qui renvoie les données attendues.

mon Code 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             
});

j'utilise la version 2.0.2 de jQuery.

toute aide sur la raison de cette erreur serait d'une grande aide.

30
demandé sur Eric Leschinski 2013-06-27 05:16:24

3 réponses

votre code tente en fait de faire un Cross-domain (CORS) demande, pas un simple POST.

C'est-à-dire: les navigateurs modernes n'autoriseront les appels Ajax vers les services que dans le même domaine comme page HTML.

Exemple: une page en http://www.example.com/myPage.html ne peut directement demander à des services qui sont http://www.example.com, comme http://www.example.com/testservice/etc. Si le service est dans un autre domaine, le navigateur ne fera pas l'appel direct (comme vous attendre.) Au lieu de cela, il essaiera de faire une demande CORS.

pour le dire rapidement, pour effectuer une requête CORS, votre navigateur:

  • envoie d'abord un OPTION demande à l'URL cible
  • Et seulement si la réponse du serveur OPTION contient des en-têtes adéquats (Access-Control-Allow-Origin est l'un d'entre eux) pour permettre la requête CORS, le browse effectuera l'appel (presque exactement comme si la page HTML était à la même domaine).
    • si les en-têtes attendus ne viennent pas, le navigateur abandonne tout simplement (comme il vous l'a fait).

Comment le résoudre? la manière la plus simple est d'activer CORS (activer les en-têtes nécessaires) sur le serveur.

si vous n'y avez pas accès côté serveur, vous pouvez créer un miroir du service web à partir d'un autre endroit, puis activer CORS là.

57
répondu acdcjunior 2013-06-27 01:22:09

Vous devez ajouter ce code dans 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();
            }
        }
5
répondu ali bencharda 2015-03-23 15:32:06

Vous pouvez créer les en-têtes dans un filtre trop.

@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);
    }
    ...
}
4
répondu user4227302 2014-11-07 14:54:42