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

Bra*_*vis 34 rest jquery post web-services wcf-rest

我正在向RESTFUL WCF服务应用程序发送一个post请求.我能够POST通过Fiddler 成功发送请求.

但是,当我通过jQuery Ajax方法执行此操作时,该函数会将以下内容返回到Chrome Developer Console:

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

但是之后的第二个日志:

Object {d: "You entered 10"} testpost.html:16
Run Code Online (Sandbox Code Playgroud)

这告诉我的是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             
});
Run Code Online (Sandbox Code Playgroud)

我使用的是jQuery 2.0.2版.

任何有关此错误发生原因的帮助都将是一个很大的帮助.

acd*_*ior 62

您的代码实际上是在尝试发出跨域(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(启用必要的标头).

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


小智 5

您必须在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();
            }
        }
Run Code Online (Sandbox Code Playgroud)