AJAX dans Chrome en envoyant des OPTIONS au lieu de GET / POST / PUT / DELETE?

Je travaille sur une application web interne au travail. Dans IE10, les requêtes fonctionnent correctement, mais dans Chrome, toutes les requêtes AJAX (qui sont nombreuses) sont envoyées via OPTIONS au lieu de la méthode définie. Techniquement, mes requêtes sont “interdomaine”. Le site est servi sur localhost: 6120 et le service pour lequel je demande des requêtes AJAX est sur 57124. Ce bogue jquery fermé définit le problème, mais pas un vrai correctif.

Que puis-je faire pour utiliser la méthode http appropriée dans les requêtes ajax?

Modifier:

Ceci est dans le chargement de document de chaque page:

jQuery.support.cors = true; 

Et chaque AJAX est construit de la même manière:

 var url = 'http://localhost:57124/My/Rest/Call'; $.ajax({ url: url, dataType: "json", data: json, async: true, cache: false, timeout: 30000, headers: { "x-li-format": "json", "X-UserName": userName }, success: function (data) { // my success stuff }, error: function (request, status, error) { // my error stuff }, type: "POST" }); 

Chrome contrôle la requête pour rechercher les en-têtes CORS . Si la requête est acceptable, elle enverra alors la requête réelle. Si vous faites ce domaine croisé, vous devrez simplement vous en occuper ou trouver un moyen de rendre la requête non interdomaine. C’est pourquoi le bogue jQuery a été fermé en tant que non-correctif. C’est par conception.

Contrairement aux requêtes simples (présentées ci-dessus), les requêtes “pré-contrôlées” envoient d’abord une requête HTTP par la méthode OPTIONS à la ressource de l’autre domaine, afin de déterminer si la requête réelle peut être envoyée en toute sécurité. Les requêtes inter-sites sont contrôlées comme ceci car elles peuvent avoir des implications sur les données utilisateur. En particulier, une demande est contrôlée en amont si:

  • Il utilise des méthodes autres que GET, HEAD ou POST. De même, si POST est utilisé pour envoyer des données de requête avec un Content-Type autre que application / x-www-form-urlencoded, multipart / form-data ou text / plain, par exemple si la requête POST envoie une charge XML au serveur en utilisant application / xml ou text / xml, la requête est pré-contrôlée.
  • Il définit des en-têtes personnalisés dans la requête (par exemple, la demande utilise un en-tête tel que X-PINGOTHER)

Compte tenu du fait que la demande n’est pas envoyée sur le port par défaut 80/443, cet appel Ajax est automatiquement considéré comme une requête CORS (Cross-Origin Resource) , ce qui signifie que la requête émet automatiquement une requête OPTIONS En-têtes CORS du côté serveur / servlet.

Cela se produit même si vous définissez

 crossOrigin: false; 

ou même si vous l’omettez.

La raison en est simplement localhost != localhost:57124 . Essayez de l’envoyer uniquement à localhost sans le port – cela échouera, car la cible demandée ne sera pas accessible, cependant, notez que si les noms de domaine sont égaux, la requête est envoyée sans la requête OPTIONS avant le POST.

Je suis d’accord avec Kevin B, le rapport de bogue dit tout. Il semble que vous essayiez de faire des appels ajax interdomaines. Si vous ne connaissez pas la même politique d’origine, vous pouvez commencer ici: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Same_origin_policy_for_JavaScript .

Si cela n’est pas destiné à être un appel ajax interdomaine, essayez de rendre votre URL cible relative et voir si le problème disparaît. Si vous êtes vraiment désespéré, jetez un coup d’œil au JSONP, mais attention, le chaos se cache. Il n’y a vraiment pas beaucoup plus à faire pour vous aider.

Si possible, passez les parameters via GET / POST standard avec un nom différent et laissez votre code côté serveur le gérer.

J’ai eu un problème similaire avec mon propre proxy pour contourner CORS et j’ai eu la même erreur de POST-> OPTION dans Chrome. C’était l’en-tête Authorization dans mon cas ( "x-li-format" et "X-UserName" dans votre cas.) J’ai fini par le passer dans un format fictif (par exemple AuthorizatinJack dans GET) et j’ai changé le code de mon proxy pour transformer cet en-tête lors de l’appel à destination. Ici c’est en PHP:

 if (isset($_GET['AuthorizationJack'])) { $request_headers[] = "Authorization: Basic ".$_GET['AuthorizationJack']; } 

Dans mon cas, j’appelle une API hébergée par AWS (API Gateway). L’erreur s’est produite lorsque j’ai essayé d’appeler l’API à partir d’un domaine autre que le propre domaine de l’API. Depuis que je suis propriétaire de l’API, j’ai activé CORS pour l’environnement de test, comme décrit dans la documentation Amazon .

En production, cette erreur ne se produira pas, car la demande et l’API seront dans le même domaine.

J’espère que ça aide!

Comme répondu par @ Falcon Falcon, je me suis contenté de m’en occuper.

Dans mon cas, j’utilise le serveur node.js et je crée une session si elle n’existe pas. Comme la méthode OPTIONS ne contient pas les détails de session, elle a fini par créer une nouvelle session pour chaque requête de méthode POST.

Donc, dans ma routine d’application pour create-session-if-not-exist, j’ai simplement ajouté une vérification pour voir si la méthode est OPTIONS , et si oui, ignorez simplement la partie qui crée la session:

  app.use(function(req, res, next) { if (req.method !== "OPTIONS") { if (req.session && req.session.id) { // Session exists next(); }else{ // Create session next(); } } else { // If request method is OPTIONS, just skip this part and move to the next method. next(); } } 

Les requêtes “pré-contrôlées” envoient d’abord une requête HTTP par la méthode OPTIONS à la ressource de l’autre domaine, afin de déterminer si la requête réelle peut être envoyée en toute sécurité. Demandes intersites

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

Pensez à utiliser des axios

 axios.get( url, { headers: {"Content-Type": "application/json"} } ).then( res => { if(res.data.error) { } else { doAnything( res.data ) } }).catch(function (error) { doAnythingError(error) }); 

J’ai eu ce problème en utilisant fetch et axios a parfaitement fonctionné.

J’ai rencontré un problème très similaire. J’ai passé presque une demi-journée à comprendre pourquoi tout fonctionne correctement dans Firefox et échoue dans Chrome. Dans mon cas, c’était à cause de champs dupliqués (ou peut-être mal saisis) dans mon en-tête de requête.