Pourquoi envoie-t-on une demande D'OPTIONS et puis-je la désactiver?

je construis une api web. J'ai trouvé que chaque fois que J'utilise Chrome pour poster, accéder à mon API, il y a toujours une requête D'OPTION envoyée avant la requête réelle, ce qui est assez ennuyeux. Actuellement, je reçois le serveur d'Ignorer toutes les requêtes D'OPTIONS. Maintenant, mes questions sont ce qui est bon d'envoyer une requête D'OPTION pour doubler la charge du serveur? Y a-t-il un moyen d'empêcher complètement le navigateur d'envoyer des requêtes D'OPTIONS?

229
demandé sur mplungjan 2015-04-29 23:37:22

15 réponses

edit 2018-09-13 : ajout de quelques précisions sur cette demande pré-vol et comment l'éviter à la fin de cette réponse.

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

ils sont nécessaires lorsque vous faites des demandes à travers différentes origines dans des situations spécifiques.

cette demande pré-vol est faite par certains navigateurs à titre de mesure de sécurité pour assurer que la requête en cours est approuvé par le serveur. Sens le serveur comprend que la méthode, l'origine et les en-têtes envoyés sur la demande sont sans danger pour agir.

votre serveur ne doit pas ignorer mais traiter ces requêtes chaque fois que vous tentez de faire des requêtes d'origine croisée.

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

une façon de les manipuler pour être à l'aise est pour s'assurer que pour n'importe quel 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 requêtes de n'importe quelle origine.

pour plus d'informations sur la façon d'ajouter le support CORS à votre serveur, consultez l'organigramme suivant

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

CORS Flowchart


edit 2018-09-13

CORS OPTIONS demande est déclenché uniquement dans certains cas, comme expliqué dans MDN docs :

Some requests don’t trigger a CORS preflight. Those are called “simple requests” in this article, though the Fetch spec (which defines CORS) doesn’t use that term. A request that doesn’t trigger a CORS preflight—a so-called “simple request”—is one that meets all the following conditions:

The only allowed methods are:
- GET
- HEAD
- POST

Apart from the headers set automatically by the user agent (for example, Connection, User-Agent, or any of the other headers with names defined in the Fetch spec as a “forbidden header name”), the only headers which are allowed to be manually set are those which the Fetch spec defines as being a “CORS-safelisted request-header”, which are:
- Accept
- Accept-Language
- Content-Language
- Content-Type (but note the additional requirements below)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width

The only allowed values for the Content-Type header are:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain

No event listeners are registered on any XMLHttpRequestUpload object used in the request; these are accessed using the XMLHttpRequest.upload property.

No ReadableStream object is used in the request.
211
répondu Leo Correa 2018-09-13 15:25:43

s'il vous Plaît consulter cette réponse sur le besoin réel de pré-flighted demande OPTIONS: de la SCRO - Quelle est la motivation derrière l'introduction du contrôle en amont des demandes?

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

  1. Demande de ne pas définir des en-têtes HTTP personnalisés comme "application/xml" ou "application/json" etc
  2. la méthode request doit être une de GET, De la TÊTE ou par la POSTE. Si le POST, un type de contenu doit être l'un des 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

121
répondu device_exec 2017-05-23 12:34:47

ont traversé cette question, ci-dessous est ma conclusion à cette question et ma solution.

selon la CORS strategy (fortement recommandé de lire à ce sujet), vous ne pouvez pas juste forcer le navigateur à cesser d'envoyer la demande D'OPTION s'il pense qu'il a besoin.

il y a deux façons de travailler

    1. assurez-vous que votre demande est une " simple demande"
    1. Set Access-Control-Max-Age pour l'OPTION "demande de 1519140920"

Simple requête

une simple demande trans-site est une demande qui remplit toutes les conditions suivantes:

les seules méthodes autorisées sont: - OBTENIR - TÊTE - POST

à L'exclusion des en-têtes configurés automatiquement par l'agent utilisateur (par exemple connexion, User-Agent, etc.), les seuls en-têtes qui peuvent être réglés manuellement sont: - Accepter - Accept-Language - Contenu-Langue - Type De Contenu

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 donnera pas lieu à une demande d'OPTION pré-vol.

définit un cache pour le contrôle D'OPTION

vous pouvez définir un Access-Control-Max-Age pour l'OPTION de demande, de sorte qu'il ne vérifiera pas la permission de nouveau jusqu'à ce qu'il est expiré.

contrôle D'accès-max-Age donne la valeur en secondes pour combien de temps la réponse à la demande pré-vol peut être mise en cache sans envoyer une autre demande pré-vol.

104
répondu Neekey 2016-11-02 06:48:33

Oui il est possible d'éviter les requêtes d'options. La demande d'Options est une demande pré-vol lorsque vous envoyez (post) des données à 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 de CORS et d'utiliser la solution readymade et il fonctionnera n'importe où.

Regardez ici: https://github.com/jpillora/xdomain

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

bonne journée!

39
répondu user889349 2015-05-18 04:30:34

lorsque la console de débogage est ouverte et que l'option Disable Cache est activée, les requêtes avant vol seront toujours envoyées (c'est-à-dire avant chaque requête). si vous ne désactivez pas le cache, une requête pré-vol ne sera envoyée qu'une seule fois (par serveur)

35
répondu Nir 2018-06-03 09:48:29

comme mentionné dans les billets précédents déjà, OPTIONS requêtes sont là pour une raison. Si vous avez un problème avec les temps de réponse élevés de votre serveur (par exemple connexion à l'étranger), vous pouvez également avoir votre cache de navigateur les requêtes pré-Lig niques.

faites répondre votre serveur avec l'en-tête Access-Control-Max-Age et pour les requêtes qui vont au même endpoint, la requête preflight aura été mise en cache et ne se produira plus.

14
répondu enpenax 2016-02-22 03:02:35

pour un développeur qui comprend la raison pour laquelle il existe, mais qui a besoin d'accéder à une API qui ne gère pas les appels D'OPTIONS sans autorisation, j'ai besoin d'une réponse temporaire afin de pouvoir développer localement jusqu'à ce que le propriétaire de L'API ajoute le support approprié de L'API CORS ou que j'obtienne une API proxy qui démarre.

j'ai trouvé que vous pouvez désactiver CORS en Safari et Chrome sur un Mac.

Désactiver la même origine dans Chrome

Chrome: Quit Chrome, ouvrir un terminal et coller cette commande: open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir

Safari: la Désactivation de l'origine de la politique dans Safari

si vous voulez désactiver la Politique de même origine sur Safari (j'ai 9.1.1), alors vous n'avez qu'à activer le menu developer, et sélectionner" Désactiver les Restrictions D'origine croisée " dans le menu develop.

12
répondu Joseph Juhnke 2017-05-23 11:47:29

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();
}

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

6
répondu AntiCZ 2017-09-10 19:47:05

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

5
répondu Jose Mato 2015-05-16 16:32:12

après avoir passé une journée et demie à essayer de résoudre un problème similaire, j'ai trouvé qu'il avait à voir avec IIS .

mon projet D'API Web a été configuré comme suit:

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

Je n'avais pas les options de configuration sur le web.config > système.noeud webServer comme j'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 Le application des paramètres du pool .

le managed pipeline mode a été mis à la classique ( l'a changé à Intégré ) et le identité a été mis au service de réseau ( l'a changé à ApplicationPoolIdentity )

changer ces paramètres (et rafraîchir l'application la piscine), il fixe pour moi.

0
répondu Ju66ernaut 2018-06-04 12:29:23

ce qui a fonctionné pour moi était d'importer "github.com/gorilla/handlers "et puis l'utiliser de cette façon:

router := mux.NewRouter()
router.HandleFunc("/config", getConfig).Methods("GET")
router.HandleFunc("/config/emcServer", createEmcServers).Methods("POST")

headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type"})
originsOk := handlers.AllowedOrigins([]string{"*"})
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})

log.Fatal(http.ListenAndServe(":" + webServicePort, handlers.CORS(originsOk, headersOk, methodsOk)(router)))

dès que j'exécutais une requête Ajax POST et y attachais des données JSON, Chrome ajoutait toujours l'en-tête Content-Type qui n'était pas dans ma précédente configuration AllowedHeaders.

-1
répondu Kurt 2017-05-17 15:52:20

je pense, vous envoyez une demande à cross domain .

Pour cross-domain "151930920 les demandes", le réglage du type de contenu à autre chose que application / x-www-form-urlencoded , multipart/form-data , ou text / plain va déclencher le navigateur pour envoyer un Preflight OPTIONS demande au serveur.

ainsi vous pouvez avoir besoin de spécifier contentType pour éviter la requête D'OPTION.

Exemple De Jquery: -

$.ajax({
    url: "http://crossdomainurl",
    type: "POST",
    contentType: 'text/plain'
}); 
-1
répondu Bala 2018-06-04 12:29:33

il y a peut-être une solution (mais je ne l'ai pas testé) : vous pouvez utiliser CSP (Content Security Policy) pour activer votre domaine distant et les navigateurs sauteront peut-être la vérification des requêtes D'OPTIONS CORS.

si je trouver un peu de temps, je vais tester ça et mise à jour de ce post !

CSP: https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Security-Policy

Spécification CSP: https://www.w3.org/TR/CSP /

-1
répondu Arnaud Tournier 2018-07-26 10:00:07

une solution que j'ai utilisée dans le passé - disons que votre site est sur mydomain.com, et vous devez faire une demande ajax pour foreigndomain.com

configurer une réécriture IIS de votre domaine vers le domaine étranger-e.g.

<rewrite>
  <rules>
    <rule name="ForeignRewrite" stopProcessing="true">
        <match url="^api/v1/(.*)$" />
        <action type="Rewrite" url="https://foreigndomain.com/{R:1}" />
    </rule>
  </rules>
</rewrite>

sur votre mydomain.com site - vous pouvez alors faire une même demande d'origine, et il n'y a pas besoin de demande d'options:)

-2
répondu David McEleney 2017-10-30 01:38:15

il peut être résolu en cas d'utilisation d'un proxy qui intercepte la requête et écrit les en-têtes appropriés. Dans le cas particulier du vernis ce serait les règles:

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

}

-2
répondu Rafa Cuestas 2018-01-31 14:23:19