38

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

但是,当我通过 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。

关于为什么会发生此错误的任何帮助将是一个很大的帮助。

4

5 回答 5

66

您的代码实际上是在尝试发出跨域 (CORS)请求,而不是普通的POST.

即:现代浏览器只允许 Ajax 调用与 HTML 页面位于同一域中的服务。

示例:中的页面http://www.example.com/myPage.html只能直接请求 中的服务http://www.example.com,例如http://www.example.com/testservice/etc。如果服务在其他域中,浏览器将不会进行直接调用(如您所料)。相反,它将尝试发出 CORS 请求。

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

  • 将首先向目标 URL 发送OPTION请求
  • 然后,只有当服务器对其的响应OPTION包含足够的标头(Access-Control-Allow-Origin其中之一)以允许 CORS 请求时,浏览器才会执行调用(几乎与 HTML 页面位于同一域中的方式完全相同)。
    • 如果没有出现预期的标题,浏览器就会放弃(就像它对你所做的那样)。

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

如果您没有服务器端访问权限,您可以从其他地方镜像 Web 服务,然后在此处启用 CORS。

于 2013-06-27T01:22:09.690 回答
6

您必须在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();
            }
        }
于 2015-03-23T14:50:24.153 回答
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);
    }
    ...
}
于 2014-11-07T14:15:25.080 回答
0

对于相同的错误代码,我有完全不同的原因,我在这里分享以提供帮助

我有如下 web api 操作

public IHttpActionResult GetBooks (int id)

我改变了接受两个参数类别和作者的方法所以我改变了参数如下,我也把属性[Httppost]

public IHttpActionResult GetBooks (int category, int author)

我还更改了 ajax 选项,如下所示,此时我开始收到错误 405 method not allowed

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)
于 2020-02-27T19:54:31.500 回答
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;

希望它可以帮助你或某人:)

于 2021-01-21T14:20:36.140 回答