web-dev-qa-db-fra.com

La réponse au contrôle en amont a un code d'état HTTP non valide 405

J'ai lu beaucoup de problèmes similaires dans StackOverflow, mais les solutions ne fonctionnent pas pour moi. 

J'ai un service WCF REST:

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

Je peux l'utiliser avec Postman (extension Chrome). Je transmets des données comme "brutes", pas "urlencodées". Et je reçois 200 code de retour.

 enter image description here

J'ai besoin d'appeler cette méthode en utilisant angularjs:

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

Je viens de copier l'URL et le JSON de Postman. Mais je reçois l'erreur:

angular.js: 10722 OPTIONS http://192.168.1.65/Service1.svc/restapi/PostItemhttp://192.168.1.65/Service1.svc/restapi/PostItem . Réponse pour preflight a un code d'état HTTP non valide 405

J'ai cherché des problèmes similaires et j'ai trouvé deux solutions:

  1. Utilisez jQuery pour définir l'en-tête Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', mais cela ne fonctionne pas avec mon service WCF
  2. Définir des en-têtes personnalisés dans mon 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>
    

Ça ne m'aide pas Et je ne suis pas sûr que la raison de l'erreur sur le serveur. L'extension Postman peut appeler cette méthode avec succès.

Comment puis-je faire le même POST appel en utilisant AngularJS?

Mettre à jour:

Voici la requête OPTIONS:

 enter image description here

Les onglets Review et Response sont vides

Mise à jour 2:

Tout fonctionne bien dans IE, mais ne fonctionne pas dans Chrome.

10
demas

On dirait que j'ai trouvé une solution. Je viens d'ajouter une deuxième méthode:

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

Ce sont juste des méthodes vides qui ne font rien. Je ne connais pas la raison, mais tout fonctionne.

6
demas

Même question fermée, je veux montrer ce qui fonctionne pour moi. 

Vous devez d’abord activer CORS sur web.config (comme 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>

Si vous avez un paramètre HEADER supplémentaire, vous devez l'ajouter à Access-Control-Allow-Headers, comme suit:

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

Enfin, pour traiter les demandes OPTIONS, vous devez répondre avec une réponse vide, en ajoutant dans votre classe d'application:

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

Bien que cela ait déjà une réponse, mais voici ma solution . Dans la configuration Web, vous devez supprimer l’instruction à <remove name="OPTIONSVerbHandler" /> 

Tout d'abord ajouter dans les 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>

Puis commentez ou supprimez l’instruction pour supprimer 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>
1
Morvael

Solution qui a fonctionné pour moi: 

  1. Ajoutez ceci à web.config (côté serveur):

     <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. Créez un fichier Global.asax (classe d'application globale) et ajoutez le code suivant: 

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

Depuis que IIS Team a publié IIS module CORS les hacks comme les méthodes vides ne sont plus nécessaires. Il traite correctement avec CORS, y compris les demandes de contrôle en amont. Vous pouvez le configurer dans la configuration Web, par exemple:

<?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>
0
Jesús López

Je viens de résoudre le même problème avec la suppression de xhr.setRequestHeader() dans ma demande AJAX. Si quelqu'un en a un dans le code, essayez de le supprimer.

0
muinh