【问题标题】:jQuery .ajax() POST Request throws 405 (Method Not Allowed) on RESTful WCFjQuery .ajax() POST 请求在 RESTful WCF 上抛出 405(不允许的方法)
【发布时间】:2013-06-24 08:32:54
【问题描述】:

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

任何有关为什么会发生此错误的帮助都会非常有帮助。

【问题讨论】:

    标签: jquery web-services rest post wcf-rest


    【解决方案1】:

    您的代码实际上是在尝试发出Cross-domain (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 的响应包含adequate headers (Access-Control-Allow-Origin is one of them) 以允许CORS 请求,浏览器将执行调用(几乎与HTML 页面的调用方式完全相同)是在同一个域)。
      • 如果没有出现预期的标头,浏览器就会放弃(就像它对您所做的那样)。

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

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

    【讨论】:

    • 好的,现在说得通了。非常感谢。
    • 不会 jsonp 也能完成这项工作 - 只要它得到服务器的支持?
    • @Sumit 如果您所做的只是GET,那么 JSONP 可能是一个选项。尽管如此,JSONP 与其说是一种解决方案,不如说是一种变通方法,因为你可以用它做非常有限的事情。你不能通过 JSONP 做POSTs(或PUTs 等)。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      您也可以在过滤器中创建所需的标题。

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

      【讨论】:

        【解决方案4】:

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

        我有如下 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)
        

        【讨论】:

          【解决方案5】:

          这对我有用

          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;

          希望它对您或某人有所帮助:)

          【讨论】:

            猜你喜欢
            • 2017-01-27
            • 2017-06-08
            • 1970-01-01
            • 2018-08-19
            • 2019-02-15
            • 2023-04-05
            • 2020-03-19
            • 1970-01-01
            • 2012-04-30
            相关资源
            最近更新 更多