it-swarm.com.de

jQuery .ajax () POST Request wirft 405 (Methode nicht zulässig) auf RESTful WCF

Ich sende eine Post-Anfrage an eine RESTFUL WCF-Serviceanwendung. Ich kann eine POST -Anforderung erfolgreich über Fiddler senden.

Wenn ich dies jedoch über die jQuery Ajax-Methode tue, gibt die Funktion Folgendes an die Chrome Developer Console zurück:

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

Aber dann eine Sekunde nach den Protokollen:

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

Dies sagt mir, dass jQuery eine OPTIONS -Anforderung sendet, die fehlschlägt, und dann eine POST -Anforderung sendet, die die erwarteten Daten zurückgibt.

Mein jQuery Code:

$.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             
});

Ich verwende jQuery Version 2.0.2.

Jede Hilfe, warum dieser Fehler auftritt, wäre eine große Hilfe.

33
Brandon Davis

Ihr Code versucht tatsächlich, eine Cross-Domain (CORS) -Anforderung zu stellen, keine gewöhnliche POST.

Das heißt: Moderne Browser erlauben nur Ajax-Aufrufe von Diensten in der gleichen Domäne wie die HTML-Seite.

Beispiel: Eine Seite in http://www.example.com/myPage.html kann nur Dienste direkt anfordern, die sich in http://www.example.com, mögen http://www.example.com/testservice/etc. Wenn sich der Dienst in einer anderen Domäne befindet, wird der direkte Anruf vom Browser nicht ausgeführt (wie erwartet). Stattdessen wird versucht, eine CORS-Anfrage zu stellen.

Kurz gesagt, um eine CORS-Anfrage auszuführen, Ihr Browser:

  • Sendet zuerst eine OPTION -Anforderung an die Ziel-URL
  • Und dann nur, wenn die Serverantwort auf dieses OPTION die entsprechenden Header (Access-Control-Allow-Origin ist einer von ihnen) Um die CORS-Anforderung zuzulassen, führt das Durchsuchen den Aufruf aus (fast genauso wie bei einer HTML-Seite in derselben Domain).
    • Wenn die erwarteten Header nicht angezeigt werden, gibt der Browser einfach auf (wie bei Ihnen).

So lösen Sie das Problem Am einfachsten aktivieren Sie CORS (aktivieren Sie die erforderlichen Header) auf dem Server.

Wenn Sie keinen serverseitigen Zugriff darauf haben, können Sie den Webdienst von einem anderen Ort aus spiegeln und dort CORS aktivieren.

61
acdcjunior

Sie müssen diesen Code in global.aspx hinzufügen:

 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
ali bencharda

Sie können die erforderlichen Header auch in einem Filter erstellen.

@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);
    }
    ...
}
3
user4227302