我正在向RESTFUL WCF服务应用程序发送一个post请求。我能够通过Fiddler成功发送POST
请求。
但是当我通过jQuery Ajax方法执行此操作时,该函数会将以下内容返回到Chrome Developer Console:
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版。
任何有关此错误发生原因的帮助都会有很大帮助。
答案 0 :(得分:58)
您的代码实际上是在尝试发出Cross-domain (CORS)请求,而不是普通的POST
。
即:现代浏览器只允许Ajax调用相同域中的服务作为HTML页面。
示例: http://www.example.com/myPage.html
中的页面只能直接请求http://www.example.com
中的服务,例如http://www.example.com/testservice/etc
。如果该服务位于其他域中,则浏览器不会进行直接调用(如您所期望的那样)。相反,它会尝试发出CORS请求。
简而言之,要执行CORS请求,请使用浏览器:
OPTION
个请求OPTION
的响应包含允许CORS请求的adequate headers (Access-Control-Allow-Origin
is one of them)时,浏览才会执行调用(几乎完全按照它的方式执行如果HTML页面位于同一个域中)。
如何解决?最简单的方法是在服务器上启用CORS(启用必要的标头)。
如果您没有服务器端访问权限,则可以从其他地方镜像Web服务,然后在那里启用CORS。
答案 1 :(得分: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();
}
}
答案 2 :(得分:4)
您也可以在过滤器中创建所需的标题。
@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);
}
...
}
答案 3 :(得分:0)
由于相同的错误代码,我有完全不同的原因,我在这里分享帮助
我有如下所示的Web api操作
public IHttpActionResult GetBooks (int id)
我更改了接受两个参数类别和作者的方法,因此我按如下所示更改了参数,我还放置了[Httppost]属性
public IHttpActionResult GetBooks (int category, int author)
我还更改了如下所示的ajax选项,这时我开始收到错误405方法不允许
var options = {
url: '/api/books/GetBooks',
type: 'POST',
dataType: 'json',
cache: false,
traditional: true,
data: {
category: 1,
author: 15
}
}
当我为Web api操作参数创建类时,如下错误消失了
public class BookParam
{
public int Category { get; set; }
public int Author { get; set; }
}
public IHttpActionResult GetBooks (BookParam param)
答案 4 :(得分:0)
这对我有用
在 Web.config 中添加以下脚本
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" >
<remove name="WebDAVModule"/>
</modules>
<handlers accessPolicy="Read, Execute, Script">
<remove name="WebDAV" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*."
verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
也在RouteConfig.cs
改变
settings.AutoRedirectMode = RedirectMode.Permanent;
到
settings.AutoRedirectMode = RedirectMode.Off;
希望它对你或某人有帮助:)