J'écris des services WCF qui seront utilisés par les clients dans la nature, ils doivent donc traiter les demandes provenant de plusieurs pays. Je ne parviens pas à autoriser mon serveur de développement à accepter de telles demandes. Voici le scénario:
Lorsque j'exécute le projet client dans IE, il n'y a pas de problème, car IE n'envoie pas la demande de contrôle en amont OPTIONS. Cependant, lorsque je l'exécute dans Chrome, la requête OPTIONS de preflight renvoie une méthode 405 non autorisée et Chrome renonce au service. Les versions précédentes de Chrome ignoraient simplement l'erreur et continuaient avec la demande POST réelle (ou Get, peu importe ...), mais les versions ultérieures semblaient plus difficiles.
J'ai également rencontré ce problème avec un projet WCF déployé et je l'ai résolu en déplaçant OPTIONSVerbHandler en haut de la liste Mappages de gestionnaires dans IIS.
Je dois préciser que j'utilise les paramètres web.config les plus généreux auxquels je puisse penser pour essayer d'autoriser la CORS. Par exemple, j'ai ceci dans la configuration du projet WCF:
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="*" />
<add name="Access-Control-Allow-Methods" value="*" />
<add name="X-Powered-By" value="*" />
</customHeaders>
</httpProtocol>
Quoi qu'il en soit, toutes les demandes de clients d'origine croisée adressées au projet WCF exécuté à partir de code échouent avec l'erreur 405.
Toute aide pour configurer le projet WCF lui-même ou IIS Express 8 pour activer CORS?
Merci!
La réponse est que la configuration nécessaire pour permettre à WCF d'accepter les messages de contrôle en amont de CORS n'a rien à voir avec le serveur IIS; le projet WCF lui-même doit plutôt être configuré pour gérer la requête HTTP avec le verbe OPTIONS.
Longue histoire courte: faire ceci est VRAIMENT DUR. WCF est un touche-à-tout en matière de points de terminaison; il est donc déconseillé de le configurer pour faire quelque chose de très spécifique avec l'un (HTTP), bien que cela puisse être fait. La vraie solution consiste à utiliser Web API, qui est un maître de HTTP et peut être configuré pour effectuer CORS très simplement.
Vous pouvez activer cors pour wcf, et cela peut être assez simple, une fois que vous savez comment faire.
En partant de la réponse de David G sur la question plus générale "cors sur IIS" , réponse qui est vraiment proche de ce qui est requis pour une solution de base:
Commencez par configurer la variable OPTIONSVerbHandler
pour qu'elle s'exécute avant les gestionnaires .Net.
OPTIONSVerbHandler
et déplacez-le vers le haut (beaucoup de clics ...).Vous pouvez également le faire dans web.config en redéfinissant tous les gestionnaires sous <system.webServer><handlers>
. (<clear>
puis <add ...>
retour, c’est ce que fait la console IIS pour vous. En passant, il n’est pas nécessaire de demander l’autorisation de "lecture" sur ce gestionnaire.)
Deuxièmement, configurez des en-têtes http personnalisés pour vos besoins cors, tels que:
<system.webServer>
<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="POST,GET,OPTIONS"/>
</customHeaders>
</httpProtocol>
</system.webServer>
Cet exemple les définit pour toutes les réponses à toutes les demandes sur le site/app/répertoire dans lequel se trouve web.config. Si vous voulez les restreindre à une URL, mettez-la dans une balise <location>
.
Vous pouvez également ajouter ces en-têtes personnalisés dans la console IIS.
Il s’agit d’une solution de base car elle enverra des en-têtes CORS même sur demande qui ne le nécessite pas, ouvrant peut-être votre application à des utilisations inattendues. Mais avec WCF, cela semble être le plus simple.
Avec MVC ou webapi, nous pourrions plutôt gérer le verbe OPTIONS
et corser les en-têtes par code ("manuellement" ou avec le support intégré disponible dans la dernière version de webapi).
Méthodes d'accès-contrôle-autoriser: GET, PUT, POST, DELETE
ou bien:
Méthodes d'accès au contrôle d'accès: PUT, DELETE
parce que la spécification dit que GET et POST sont impliqués.
Je voulais simplement mentionner que, au moment de la rédaction de ce document, je ne pense pas que les navigateurs Web prennent en charge la valeur générique * pour Access-Control-Allow-Methods
ou Access-Control-Allow-Headers
, même si elle est conforme aux spécifications.
Spec:
https://www.w3.org/TR/cors/
https://tools.ietf.org/html/rfc2616#section-4.2
Voir Notes de compatibilité (lecture plus facile):
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methodshttps://developer.mozilla.org/ en-US/docs/Web/HTTP/En-têtes/Contrôle d'accès, en-têtes autorisés
Au lieu de ce qui précède, de meilleures solutions, cela signifie que vous devez explicitement fournir chaque en-tête ou méthode que vous souhaitez autoriser.
Je ne suis pas sûr que ce soit vraiment difficile, comme le dit djo.dadof2
. L'une des réponses ci-dessus parle de l'utilisation de la console IIS, mais la question concerne le IIS Express. Pour être juste, il est question de déplacer OPTIONSVerbHandler
plus haut, ce qui peut en fait fonctionner dans IIS Express, mais vous devez effacer tous les gestionnaires et les rajouter, sans console telle que IIS. _ a, c’est difficile car vous ne savez pas lesquels ajouter. A partir de cette réponse, Appelez le service WCF de JQuery: la requête OPTIONS cross-Origin donne l'erreur 400 , vous pouvez voir que tout ce dont vous avez besoin est de gérer la requête OPTIONS dans Global.asax.cs, Application_BeginRequest
. J'ai ajouté
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "content-type");
HttpContext.Current.Response.End();
}
Et ensemble avec
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="null" />
</customHeaders>
</httpProtocol>
dans la section webconfig system.webServer
qui a fonctionné pour moi. Notez que j'ai utilisé content-type
dans l'en-tête Access-Control-Allow-Headers
pour faire correspondre ce que Firefox envoyait, et null
dans le Access-Control-Allow-Origin
car j'ouvrais une page html à partir du lecteur local.