Pourquoi une demande OPTIONS est-elle envoyée et puis-je la désactiver?

Je construis un api web. J’ai trouvé à chaque fois que j’utilisais Chrome pour POST, GET pour mon API, il y a toujours une requête OPTION envoyée avant la requête réelle, ce qui est assez ennuyeux. Actuellement, le serveur ignore toute requête OPTIONS. Maintenant, mes questions sont-elles bonnes pour envoyer une requête OPTION pour doubler la charge du serveur? Est-il possible d’empêcher complètement le navigateur d’envoyer des requêtes OPTIONS?

OPTIONS requêtes OPTIONS sont ce que nous appelons pre-flight demandes de pre-flight dans le Cross-origin resource sharing (CORS) .

Ils sont nécessaires lorsque vous effectuez des requêtes de différentes origines dans des situations spécifiques.

Cette demande de pré-vol est effectuée par certains navigateurs à titre de mesure de sécurité pour garantir que la requête en cours est approuvée par le serveur. Ce qui signifie que le serveur comprend que la méthode, l’origine et les en-têtes envoyés sur la demande peuvent être utilisés en toute sécurité.

Votre serveur ne doit pas ignorer mais gérer ces requêtes chaque fois que vous tentez d’effectuer des requêtes d’origine croisée.

Une bonne ressource peut être trouvée ici http://enable-cors.org/

Une façon de les gérer pour être à l’aise est de s’assurer que pour tout chemin avec la méthode OPTIONS , 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 l’ajout du support CORS à votre serveur, voir l’organigramme suivant

http://www.html5rocks.com/static/images/cors_server_flowchart.png

Organigramme de la SCRO

Référez-vous à cette réponse sur le besoin réel d’une demande d’OPTIONS pré-volées: CORS – Quelle est la motivation derrière l’introduction des demandes de contrôle en amont?

Pour désactiver la requête OPTIONS, les conditions ci-dessous doivent être remplies pour la requête ajax:

  1. La requête ne définit pas les en-têtes HTTP personnalisés comme “application / xml” ou “application / json”, etc.
  2. La méthode de demande doit être l’une des méthodes GET, HEAD ou POST. Si POST, le type de contenu doit être un type d’ application/x-www-form-urlencoded , multipart/form-data ou text/plain

Référence: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

J’ai parcouru ce problème, voici ma conclusion à ce problème et à ma solution.

Selon la stratégie CORS (il est fortement recommandé de lire à ce sujet) Vous ne pouvez pas forcer le navigateur à arrêter l’envoi d’une requête OPTION s’il le juge nécessaire.

Il y a deux façons de contourner le problème

    1. Assurez-vous que votre demande est une “demande simple”
    1. Définir Access-Control-Max-Age pour la requête OPTION

Demande simple

Une simple demande intersites est une demande qui remplit toutes les conditions suivantes:

Les seules méthodes autorisées sont: – GET – HEAD – POST

Outre les en-têtes définis automatiquement par l’agent utilisateur (par exemple, Connection, User-Agent, etc.), les seuls en-têtes autorisés à être définis manuellement sont: – Accept – Accept-Language – Content-Language – Content-Type

Les seules valeurs autorisées pour l’en-tête Content-Type sont: – application / x-www-form-urlencoded – multipart / form-data – text / plain

Une simple demande ne provoquera pas de demande OPTION avant le vol.

Définir un cache pour la vérification OPTION

Vous pouvez définir un Access-Control-Max-Age pour la demande OPTION afin qu’il ne vérifie plus l’autorisation avant l’expiration.

Access-Control-Max-Age donne la valeur en secondes de la durée pendant laquelle la réponse à la demande de contrôle en amont peut être mise en cache sans envoyer une autre demande de contrôle en amont.

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 à un autre domaine. C’est un problème de sécurité de 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 la solution readymade et cela fonctionnera n’importe où.

Jetez un oeil ici: https://github.com/jpillora/xdomain

Et exemple de travail: http://jpillora.com/xdomain/

Bonne journée!

Lorsque la console de débogage est ouverte et que l’option Disable Cache 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).

Comme mentionné dans les messages précédents déjà, les requêtes OPTIONS sont là pour une raison. Si vous rencontrez un problème avec des 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 Access-Control-Max-Age et, pour les demandes allant au même sharepoint terminaison, la demande de contrôle en amont sera mise en cache et ne se produira plus.

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 développer localement jusqu’à ce que le propriétaire de l’API ajoute le support SPA CORS ou 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 stratégie d’origine dans Safari

Si vous souhaitez désactiver la stratégie de même origine sur Safari (j’ai 9.1.1), il vous suffit d’activer le menu du développeur et de sélectionner “Désactiver les ressortingctions d’origine croisée” dans le menu de développement.

J’ai résolu ce problème comme.

 if($_SERVER['REQUEST_METHOD'] == 'OPTIONS' && ENV == 'devel') { header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Headers: X-Requested-With'); header("HTTP/1.1 200 OK"); die(); } 

C’est seulement pour le développement. Avec ceci j’attends 9ms et 500ms et pas 8s et 500ms. Je peux le faire parce que l’application de production JS sera sur la même machine que la production, donc il n’y aura pas d’ OPTIONS mais le développement est mon local.

Vous ne pouvez pas mais vous pouvez éviter CORS en utilisant JSONP.

Après avoir passé une journée et demie à essayer de résoudre un problème similaire, je l’ai trouvé lié à IIS .

Mon projet d’API Web a été configuré comme suit:

 // WebApiConfig.cs public static void Register(HttpConfiguration config) { var cors = new EnableCorsAtsortingbute("*", "*", "*"); config.EnableCors(cors); //... } 

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 beaucoup d’articles.

Pas de code spécifique CORS dans le fichier global.asax ou dans le contrôleur en tant que décorateur

Le problème était les parameters du pool d’applications .

Le mode de pipeline géré a été défini sur classique ( il est devenu intégré ) et l’ identité a été définie sur Service réseau (a été modifiée en ApplicationPoolIdentity ).

La modification de ces parameters (et l’actualisation du pool d’applications) l’ont corrigé.

Ce qui a fonctionné pour moi a été d’importer “github.com/gorilla/handlers” et de l’utiliser comme suit:

 router := mux.NewRouter() router.HandleFunc("/config", getConfig).Methods("GET") router.HandleFunc("/config/emcServer", createEmcServers).Methods("POST") headersOk := handlers.AllowedHeaders([]ssortingng{"X-Requested-With", "Content-Type"}) originsOk := handlers.AllowedOrigins([]ssortingng{"*"}) methodsOk := handlers.AllowedMethods([]ssortingng{"GET", "HEAD", "POST", "PUT", "OPTIONS"}) log.Fatal(http.ListenAndServe(":" + webServicePort, handlers.CORS(originsOk, headersOk, methodsOk)(router))) 

Dès que j’exécute une requête Ajax POST et que je lui associe des données JSON, Chrome ajoute toujours l’en-tête Content-Type qui ne figure pas dans ma précédente configuration AllowedHeaders.

Je pense que vous envoyez une demande pour traverser le domaine .

Pour les requêtes interdomaine, définir le type de contenu sur autre chose que application / x-www-form-urlencoded , multipart / form-data ou text / plain déclenchera le navigateur pour envoyer une requête OPTIONS de contrôle en amont au serveur.

Vous devrez donc peut-être spécifier contentType pour éviter toute demande OPTION.

Jquery Exemple: –

 $.ajax({ url: "http://crossdomainurl", type: "POST", contentType: 'text/plain' }); 

Il y a 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 vont peut-être ignorer la vérification des requêtes CORS OPTIONS.

Je trouve quelque temps, je vais tester ça 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/

Une solution que j’ai utilisée par le passé – disons que votre site est sur mydomain.com, et que vous devez faire une requête ajax sur foreigndomain.com

Configurez une réécriture IIS à partir 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 🙂

Il peut être résolu en cas d’utilisation d’un proxy interceptant la requête et écrivant les en-têtes appropriés. Dans le cas particulier de Vernis, ces règles seraient les suivantes:

 if (req.http.host == "CUSTOM_URL" ) { set resp.http.Access-Control-Allow-Origin = "*"; if (req.method == "OPTIONS") { set resp.http.Access-Control-Max-Age = "1728000"; set resp.http.Access-Control-Allow-Methods = "GET, POST, PUT, DELETE, PATCH, OPTIONS"; set resp.http.Access-Control-Allow-Headers = "Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since"; set resp.http.Content-Length = "0"; set resp.http.Content-Type = "text/plain charset=UTF-8"; set resp.status = 204; } 

}