jQuery .ajax() POST Request throws 405 (Method Not Allowed) on RESTful WCF
Solution 1
Your code is actually attempting to make a Cross-domain (CORS) request, not an ordinary POST
.
That is: Modern browsers will only allow Ajax calls to services in the same domain as the HTML page.
Example: A page in http://www.example.com/myPage.html
can only directly request services that are in http://www.example.com
, like http://www.example.com/testservice/etc
. If the service is in other domain, the browser won't make the direct call (as you'd expect). Instead, it will try to make a CORS request.
To put it shortly, to perform a CORS request, your browser:
- Will first send an
OPTION
request to the target URL - And then only if the server response to that
OPTION
contains the adequate headers (Access-Control-Allow-Origin
is one of them) to allow the CORS request, the browse will perform the call (almost exactly the way it would if the HTML page was at the same domain).- If the expected headers don't come, the browser simply gives up (like it did to you).
How to solve it? The simplest way is to enable CORS (enable the necessary headers) on the server.
If you don't have server-side access to it, you can mirror the web service from somewhere else, and then enable CORS there.
Solution 2
You must add this code 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();
}
}
Solution 3
You can create the required headers in a filter too.
@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);
}
...
}
Brandon Davis
I am a motivated 18 year old developer interested in HTML, CSS, Javascript, PHP, C#, jQuery, and Mobile Development for Android, iOS, and Windows.
Updated on January 22, 2021Comments
-
Brandon Davis over 3 years
I am sending a post request to a RESTFUL WCF service application. I am able to successfully send a
POST
request through Fiddler.However when I do this through the jQuery Ajax method the function returns the following to the Chrome Developer Console:
OPTIONS http://www.example.com/testservice/service1.svc/GetData 405 (Method Not Allowed) jquery.min.js:6
But then a second after logs:
Object {d: "You entered 10"} testpost.html:16
What this tells me is that jQuery is sending a
OPTIONS
request, which fails, and then sending aPOST
request which returns the expected data.My 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 });
I am using jQuery version 2.0.2.
Any help on why this error is occurring would be a great help.
-
Brandon Davis almost 11 yearsOkay it makes sense now. Thank you very much.
-
ProblemsOfSumit almost 10 yearswould't
jsonp
also do the job - as long as it's supported by the server? -
acdcjunior almost 10 years@Sumit If all you do is
GET
, then JSONP could be an option. Still, JSONP is more of a workaround than a solution, since you can do very limited things with it. You cant doPOST
s (orPUT
s etc.) through JSONP.