jQuery .ajax()POST请求在RESTful WCF上抛出405(方法不允许)

我正在向RESTFUL WCF服务应用程序发送一个post请求。 我能够通过Fiddler成功发送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。

任何帮助,为什么这个错误发生将是一个很大的帮助。

你的代码实际上是试图做一个跨域(CORS)的请求 ,而不是一个普通的POST

那就是:现代浏览器只允许Ajax调用与HTML页面在同一个域中的服务。

例如: http://www.example.com/myPage.html : http://www.example.com/myPage.html的页面只能直接请求http://www.example.com/myPage.html中的服务,如http://www.example.com/testservice/etc 。 如果服务在其他域中,则浏览器将不会直接调用(如您所期望的那样)。 相反,它会尝试提出一个CORS请求。

简而言之,执行CORS请求,您的浏览器:

  • 将首先发送一个OPTION请求到目标URL
  • 然后, 只有当服务器对该OPTION响应包含适当的头部( Access-Control-Allow-Origin是其中之一)以允许CORS请求时,浏览才会执行调用(几乎就像HTML页面在同一个域名)。
    • 如果预期的标题不来,浏览器只是放弃(就像你做的那样)。

如何解决? 最简单的方法是在服务器上启用CORS(启用必要的标题)。

如果您没有服务器端访问权限,则可以从其他位置镜像Web服务,然后在其中启用CORS。

您必须在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(); } } 

您也可以在filter中创build所需的标题。

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