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