edit 2018-09-13 : ajout de quelques précisions sur cette demande de pré-vol et comment l'éviter à la fin de cette réponse.
OPTIONS
les demandes sont ce que nous appelons des pre-flight
demandes Cross-origin resource sharing (CORS)
.
Ils sont nécessaires lorsque vous effectuez des demandes d'origines différentes dans des situations spécifiques.
Cette demande de pré-vol est effectuée par certains navigateurs par mesure de sécurité pour garantir que la demande en cours est approuvée par le serveur. Cela signifie que le serveur comprend que la méthode, l'origine et les en-têtes envoyés sur la demande sont sûrs d'agir.
Votre serveur ne doit pas ignorer mais gérer ces demandes chaque fois que vous essayez de faire des demandes d'origine croisée.
Une bonne ressource peut être trouvée ici http://enable-cors.org/
Un moyen de les gérer pour être à l'aise est de s'assurer que pour tout chemin avec OPTIONS
méthode, le serveur envoie une réponse avec cet en-tête
Access-Control-Allow-Origin: *
Cela indiquera au navigateur que le serveur est prêt à répondre aux demandes de toute origine.
Pour plus d'informations sur la façon d'ajouter la prise en charge CORS à votre serveur, voir l'organigramme suivant
http://www.html5rocks.com/static/images/cors_server_flowchart.png
modifier 2018-09-13
La OPTIONS
demande CORS n'est déclenchée que dans certains cas, comme expliqué dans les documents MDN :
Certaines demandes ne déclenchent pas de contrôle en amont CORS. Celles-ci sont appelées «demandes simples» dans cet article, bien que la spécification Fetch (qui définit CORS) n'utilise pas ce terme. Une demande qui ne déclenche pas un contrôle en amont CORS - une soi-disant «demande simple» - est celle qui remplit toutes les conditions suivantes:
Les seules méthodes autorisées sont:
Hormis les en-têtes définis automatiquement par l'agent utilisateur (par exemple, Connection, User-Agent ou tout autre en-tête dont le nom est défini dans la spécification Fetch comme «nom d'en-tête interdit»), les seuls en-têtes autorisés à être définies manuellement sont celles que la spécification Fetch définit comme étant un «en-tête de demande sécurisé CORS», qui sont:
- J'accepte
- Accept-Language
- Langue du contenu
- Type de contenu (mais notez les exigences supplémentaires ci-dessous)
- DPR
- Liaison descendante
- Enregistrer des données
- Largeur de la fenêtre
- Largeur
Les seules valeurs autorisées pour l'en-tête Content-Type sont:
- application / x-www-form-urlencoded
- multipart / form-data
- texte simple
Aucun écouteur d'événement n'est enregistré sur aucun objet XMLHttpRequestUpload utilisé dans la demande; ceux-ci sont accessibles à l'aide de la propriété XMLHttpRequest.upload.
Aucun objet ReadableStream n'est utilisé dans la demande.
curl
api, cela fonctionne, mais lors de l'exécution de Chrome, j'obtiens l'erreur?Origin
tête à votre demande pour simuler comme si la demande provenait d'un hôte spécifique (par exemple, votre site Web.com). Vous pouvez également simuler des demandes de contrôle en amont en définissant la méthode HTTP d'une demandeOPTIONS
et les en-Access-Control-*
têtesJ'ai traversé ce problème, voici ma conclusion à ce problème et ma solution.
Selon la stratégie CORS (je vous recommande fortement de lire à ce sujet) Vous ne pouvez pas simplement forcer le navigateur à arrêter d'envoyer une demande OPTIONS s'il le pense.
Vous pouvez contourner ce problème de deux manières:
Access-Control-Max-Age
pour la demande OPTIONSDemande simple
Une simple demande intersite répond à toutes les conditions suivantes:
Les seules méthodes autorisées sont:
Hormis les en-têtes définis automatiquement par l'agent utilisateur (par exemple, Connection, User-Agent, etc.), les seuls en-têtes qui peuvent être définis manuellement sont:
Les seules valeurs autorisées pour l'en-tête Content-Type sont:
Une simple demande n'entraînera pas de demande d'OPTIONS avant le vol.
Définir un cache pour la vérification OPTIONS
Vous pouvez définir un
Access-Control-Max-Age
pour la demande OPTIONS, afin qu'il ne vérifie pas à nouveau l'autorisation jusqu'à son expiration.Limitation notée
Access-Control-Max-Age
est -ce600
qui est de 10 minutes, en fonction de chrome code sourceAccess-Control-Max-Age
ne fonctionne que pour une ressource à chaque fois, par exemple, lesGET
demandes avec le même chemin URL mais différentes requêtes seront traitées comme des ressources différentes. Ainsi, la demande adressée à la deuxième ressource déclenchera toujours une demande de contrôle en amont.la source
Access-Control-Max-Age
. Voilà la clé ici. Il vous aide à éviter les demandes de contrôle en amont excessives.application/json
simplement parce que cela rend votre demande non "simple" (et déclenche donc CORS). Le navigateur fait son travail. Configurez votre serveur pour renvoyer quelque chose comme un en-têteAccess-Control-Max-Age: 86400
et le navigateur ne renverra pas de demande OPTIONS pendant 24 heures.Veuillez vous référer à cette réponse sur le besoin réel d'une demande OPTIONS pré-volée: CORS - Quelle est la motivation derrière l'introduction des demandes de contrôle en amont?
Pour désactiver la demande OPTIONS, les conditions ci-dessous doivent être remplies pour la demande ajax:
application/x-www-form-urlencoded
,multipart/form-data
outext/plain
Référence: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
la source
application/xml
ouapplication/json
ne sont pas des "en-têtes HTTP personnalisés". L'en-tête lui-même seraitContent-Type
et appeler cet en-tête "personnalisé" serait trompeur.Lorsque la console de débogage est ouverte et que l'
Disable Cache
option est activée, les demandes de contrôle en amont sont toujours envoyées (c'est-à-dire avant chaque demande). si vous ne désactivez pas le cache, une demande de pré-vol ne sera envoyée qu'une seule fois (par serveur)la source
Oui, il est possible d'éviter la demande d'options. La demande d'options est une demande de contrôle en amont lorsque vous envoyez (publiez) des données vers un autre domaine. C'est un problème de sécurité du navigateur. Mais nous pouvons utiliser une autre technologie: la couche de transport iframe. Je vous recommande fortement d'oublier toute configuration CORS et d'utiliser une solution prête à l'emploi et cela fonctionnera n'importe où.
Jetez un œil ici: https://github.com/jpillora/xdomain
Et exemple de travail: http://jpillora.com/xdomain/
la source
Pour un développeur qui comprend la raison de son existence mais doit accéder à une API qui ne gère pas les appels OPTIONS sans authentification, j'ai besoin d'une réponse temporaire pour pouvoir développer localement jusqu'à ce que le propriétaire de l'API ajoute le support SPA CORS approprié ou que j'obtienne une API proxy opérationnel.
J'ai trouvé que vous pouvez désactiver CORS dans Safari et Chrome sur un Mac.
Désactiver la même politique d'origine dans Chrome
Chrome: Quittez Chrome, ouvrez un terminal et collez cette commande:
open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
Safari: désactivation de la politique de même origine dans Safari
la source
Comme déjà mentionné dans les articles précédents, les
OPTIONS
demandes sont là pour une raison. Si vous rencontrez un problème avec les temps de réponse importants de votre serveur (par exemple, une connexion à l'étranger), vous pouvez également demander à votre navigateur de mettre en cache les demandes de contrôle en amont.Demandez à votre serveur de répondre avec l'en-
Access-Control-Max-Age
tête et pour les demandes qui vont au même point de terminaison, la demande de contrôle en amont aura été mise en cache et ne se produira plus.la source
OPTIONS
requêtes soient mises en cache avec cet en-tête est assez opaque dans toute la documentation CORS que j'ai lue.J'ai résolu ce problème comme.
C'est uniquement pour le développement. Avec cela j'attends 9ms et 500ms et non 8s et 500ms. Je peux le faire parce que l'application JS de production sera sur la même machine que la production, donc il n'y en aura pas
OPTIONS
mais le développement est mon local.la source
Vous ne pouvez pas mais vous pouvez éviter CORS en utilisant JSONP.
la source
Après avoir passé une journée et demie à essayer de résoudre un problème similaire, j'ai trouvé que cela avait à voir avec IIS .
Mon projet d'API Web a été configuré comme suit:
Je n'avais pas d'options de configuration spécifiques à CORS dans le nœud web.config> system.webServer comme je l'ai vu dans tant de messages
Pas de code spécifique CORS dans le global.asax ou dans le contrôleur en tant que décorateur
Le problème était les paramètres du pool d'applications .
Le mode de pipeline géré a été défini sur classique (l'a changé en intégré ) et l' identité a été définie sur Service réseau (l'a changé sur ApplicationPoolIdentity )
La modification de ces paramètres (et l'actualisation du pool d'applications) l'a corrigé pour moi.
la source
Ce qui a fonctionné pour moi, c'était d'importer "github.com/gorilla/handlers", puis de l'utiliser de cette façon:
Dès que j'exécute une demande Ajax POST et que je lui attache des données JSON, Chrome ajoute toujours l'en-tête Content-Type qui ne figurait pas dans ma précédente configuration AllowedHeaders.
la source
Une solution que j'ai utilisée dans le passé - disons que votre site se trouve sur mydomain.com et que vous devez faire une demande ajax à foreigndomain.com
Configurez une réécriture IIS de votre domaine vers le domaine étranger - par exemple
sur votre site mydomain.com - vous pouvez alors faire une même demande d'origine, et aucune demande d'options n'est nécessaire :)
la source
Il peut être résolu en cas d'utilisation d'un proxy qui intercepte la demande et écrit les en-têtes appropriés. Dans le cas particulier du vernis, ce seraient les règles:
}
la source
Il existe peut-être une solution (mais je ne l'ai pas testée): vous pouvez utiliser CSP (Content Security Policy) pour activer votre domaine distant et les navigateurs ignoreront peut-être la vérification de la demande CORS OPTIONS.
Si je trouve un peu de temps, je vais tester cela et mettre à jour ce post!
CSP: https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Security-Policy
Spécification CSP: https://www.w3.org/TR/CSP/
la source