预检的响应具有无效的HTTP状态代码405

时间:2015-11-04 05:55:45

标签: javascript angularjs wcf rest

我在StackOverflow中已经阅读了很多类似的问题,但这些解决方案并不适用于我。

我有WCF REST服务:

[<OperationContract>]    
    [<WebInvoke(UriTemplate = "PostItem", 
            RequestFormat= WebMessageFormat.Json,   
            ResponseFormat = WebMessageFormat.Json, Method = "POST")>]         

我可以使用Postman(Chrome扩展程序)使用它。我将数据传递为'raw',而不是'urlencoded'。我得到200返回代码。

enter image description here

我需要使用angularjs调用此方法:

    $http.post('http://192.168.1.65/Service1.svc/restapi/PostItem',                   
                {
    "Address": "г. Москва, ул. Соколово-Мещерская, д.25",
     ...
    "User": ""
      })  

我刚从Postman复制了URL和JSON。但是我得到了错误:

  

angular.js:10722选项   http://192.168.1.65/Service1.svc/restapi/PostItem   http://192.168.1.65/Service1.svc/restapi/PostItem。回应   预检具有无效的HTTP状态代码405

我搜索过类似的问题并找到了两个解决方案:

  1. 使用jQuery设置标头Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',但它不适用于我的WCF服务
  2. 在我的Web.Config中设置自定义标题:

    <httpProtocol>
       <customHeaders>
          <add name="Access-Control-Allow-Origin" value="*" />
          <add name="Access-Control-Allow-Headers" value="Content-Type" />
          <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
       </customHeaders>
    </httpProtocol>
    
  3. 这对我没有帮助。而且我不确定服务器端出错的原因。 Postman扩展可以成功调用此方法。

    如何使用AngularJS进行相同的POST调用?

    更新

    这是OPTIONS请求:

    enter image description here

    审核和响应标签为空

    更新2:

    一切正常,但在Chrome中无效。

6 个答案:

答案 0 :(得分:24)

即使是封闭的问题,我想展示一下对我有用的东西。

首先你必须在web.config上启用CORS(就像Mihai sad):

<httpProtocol>
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Headers" value="Content-Type" />
    <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE,     OPTIONS" />
  </customHeaders>
</httpProtocol>

如果您有一些额外的HEADER参数,则必须将其添加到Access-Control-Allow-Headers,例如:

<add name="Access-Control-Allow-Headers" value="Content-Type, X-Your-Extra-Header-Key" />

最后,要处理OPTIONS请求,您必须回复空响应,并在您的应用程序类中添加:

protected void Application_BeginRequest()
{
    if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
    {
        Response.Flush();
    }
}

答案 1 :(得分:7)

看起来我找到了解决方案。我刚刚添加了第二种方法:

[<OperationContract>]    
[<WebInvoke(UriTemplate = "PostTest", 
        RequestFormat= WebMessageFormat.Json,   
        ResponseFormat = WebMessageFormat.Json, Method = "POST")>]         
abstract PostTest: obj: Test -> unit

[<OperationContract>]    
[<WebInvoke(UriTemplate = "PostTest", 
        RequestFormat= WebMessageFormat.Json,   
        ResponseFormat = WebMessageFormat.Json, Method = "OPTIONS")>]         
abstract PostTestOptions: unit -> unit

只是空方法什么都不做。我不知道原因,但一切正常。

答案 2 :(得分:1)

虽然这已经有了答案,但继续我的解决方案。 在Web配置中,您必须删除指令export abstract class Collection<T> { protected _collection: Map<number, T>; public hydrate(key: number, item: T): this { this._collection.set(key, item); return this; } ... } export class Tours extends Collection<Tour> { }

首先添加customHeaders

<remove name="OPTIONSVerbHandler" />

然后注释掉或删除指令以删除OPTIONSverbHandler

<httpProtocol>
  <!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS -->
  <customHeaders>
    <add name="Access-Control-Allow-Origin" value="*" />
    <add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" />
    <add name="Access-Control-Allow-Headers" value="content-Type, accept, origin, X-Requested-With, X-Authentication, name" />
  </customHeaders>
</httpProtocol>

答案 3 :(得分:0)

由于IIS团队发布了IIS CORS module黑客,因此不再需要空方法了。它正确处理包括预检请求在内的CORS。您可以在Web配置中配置它,例如:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <cors enabled="true" failUnlistedOrigins="true">
            <add origin="*" />
            <add origin="https://*.microsoft.com"
                 allowCredentials="true"
                 maxAge="120"> 
                <allowHeaders allowAllRequestedHeaders="true">
                    <add header="header1" />
                    <add header="header2" />
                </allowHeaders>
                <allowMethods>
                     <add method="DELETE" />
                </allowMethods>
                <exposeHeaders>
                    <add header="header1" />
                    <add header="header2" />
                </exposeHeaders>
            </add>
            <add origin="http://*" allowed="false" />
        </cors>
    </system.webServer>
</configuration>

答案 4 :(得分:0)

我刚刚在AJAX请求中删除stmt.c时解决了同样的问题。如果有人在代码中有一个,请尝试将其删除。

答案 5 :(得分:0)

对我有用的解决方案:

  1. 将其添加到web.config(服务器端):

     <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE,  OPTIONS" />
      </customHeaders>
    </httpProtocol>
    
  2. 创建一个Global.asax文件(全局应用程序类)并添加以下代码:

        protected void Application_BeginRequest(object sender, EventArgs e){
            if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
                {
                    Response.Flush();
                }
        }