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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33514687/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:10:00  来源:igfitidea点击:

Response for preflight has invalid HTTP status code 405

javascriptangularjswcfrest

提问by demas

I have read many similar problems in StackOverflow, but the solutions doesn't work for me.

我在 StackOverflow 中阅读了许多类似的问题,但这些解决方案对我不起作用。

I have WCF REST service:

我有 WCF REST 服务:

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

I can use it using Postman (Chrome extension). I am passing data as 'raw', not 'urlencoded'. And I get 200 return code.

我可以使用 Postman(Chrome 扩展程序)来使用它。我将数据作为“原始”而不是“urlencoded”传递。我得到 200 返回码。

enter image description here

在此处输入图片说明

I need to call this method using angularjs:

我需要使用 angularjs 调用这个方法:

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

I have just copied URL and JSON from Postman. But I get the error:

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

angular.js:10722 OPTIONS http://192.168.1.65/Service1.svc/restapi/PostItemhttp://192.168.1.65/Service1.svc/restapi/PostItem. Response for preflight has invalid HTTP status code 405

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

I have searched similar problems and have found two solutions:

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

  1. Use jQuery to set header Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', but it doesn't work with my WCF service
  2. Set custom headers in my 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>
    
  1. 使用 jQuery 设置 header 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>
    

It doesn't help me. And I am not sure that the reason of the error on the server side. The Postman extension can call this method succesfully.

它对我没有帮助。而且我不确定服务器端错误的原因。Postman 扩展可以成功调用此方法。

How can I make the same POST call using AngularJS ?

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

Update:

更新

Here is OPTIONS request:

这是 OPTIONS 请求:

enter image description here

在此处输入图片说明

Review and Response tabs are empty

Review 和 Response 选项卡为空

Update 2:

更新 2:

All works fine in IE, but doesn't work in Chrome.

在 IE 中一切正常,但在 Chrome 中不起作用。

采纳答案by demas

Looks like I have found solution. I just added second method:

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

[<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

It is just empty methods that do nothing. I don't know the reason, but all is working.

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

回答by Tiago Gouvêa

I want to show what work for me.

我想展示什么对我有用。

First you must enable CORSon web.config(like Mihai sad):

首先,您必须启用CORSweb.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>

If you have some extra HEADER parameter, you must add it to Access-Control-Allow-Headers, like:

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

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

And finally, to handle OPTIONS requests you must reply with empty response, adding in your application class:

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

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

回答by Morvael

Although this already has an answer, but heres my solution. In the web config you have to remove the instruction to <remove name="OPTIONSVerbHandler" />

虽然这已经有了答案,但这是我的解决方案。在网络配置中,您必须删除指令<remove name="OPTIONSVerbHandler" />

First add in the customHeaders

首先添加customHeaders

<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>

Then either comment out or delete the instruction to remove the OPTIONSverbHandler

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

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <!-- <remove name="OPTIONSVerbHandler" /> -->
  <remove name="TRACEVerbHandler" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

回答by Jesús López

Since IIS Team published IIS CORS modulehacks like empty methods are not needed anymore. It deals with CORS including preflight requests properly. You can configure it in the web config for example:

由于 IIS 团队发布了IIS CORS 模块,因此不再需要诸如空方法之类的技巧。它正确处理包括预检请求在内的 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>

回答by muinh

I have just solved the same problem with deleting xhr.setRequestHeader()in my AJAX request. If someone has one in code, try to remove it.

我刚刚解决了xhr.setRequestHeader()在我的 AJAX 请求中删除相同的问题。如果有人在代码中有一个,请尝试将其删除。

回答by Tech Enthusiast

Solution that worked for me:

对我有用的解决方案:

  1. Add this to web.config (server-side):

     <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. Create a Global.asax file (Global application class) and add the following code:

        protected void Application_BeginRequest(object sender, EventArgs e){
            if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
                {
                    Response.Flush();
                }
        }
    
  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();
                }
        }