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