на jQuery.ajax () POST запрос бросает 405 (метод не разрешен) на RESTful WCF

Я отправляю запрос post в приложение-службу RESTFUL WCF. Я могу успешно отправить POST запрос через скрипач.

однако, когда я делаю это с помощью метода jQuery Ajax, функция возвращает в консоль разработчика Chrome следующее:

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

но затем через секунду после логов:

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

это говорит мне о том, что jQuery отправляет OPTIONS запрос, который терпит неудачу, а затем отправляет POST запрос, который возвращает ожидаемые данные.

мой код 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             
});

Я использую jQuery версии 2.0.2.

любая помощь о том, почему эта ошибка возникает, будет большой помощью.

3 ответов


ваш код фактически пытается сделать кросс-домен (CORS) запрос, не обычный POST.

то есть: современные браузеры будут разрешать Ajax-вызовы служб только в тот же домен как HTML-страница.

пример: страница http://www.example.com/myPage.html можно только напрямую обращаться за услугами в http://www.example.com, как http://www.example.com/testservice/etc. Если служба находится в другом домене, браузер не будет совершать прямой вызов (как вы ожидать.) Вместо этого он попытается сделать запрос CORS.

короче говоря, чтобы выполнить запрос CORS, Ваш браузер:

  • сначала отправить OPTION запрос к целевому URL
  • а то только если ответ сервера OPTION содержит адекватные заголовки (Access-Control-Allow-Origin один из них) чтобы разрешить запрос CORS, обзор выполнит вызов (почти точно так же, как если бы HTML-страница была на тот же домен).
    • если ожидаемые заголовки не приходят, браузер просто сдается (как это было с вами).

как ее решить? самый простой способ-включить CORS (включить необходимые заголовки) на сервере.

если у вас нет доступа к нему на стороне сервера, вы можете отразить веб-службу откуда-то еще, а затем включить CORS там.


вы должны добавить этот код в глобальные.аспн:

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

вы также можете создать необходимые заголовки в фильтре.

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