web-dev-qa-db-fra.com

Pourquoi cette demande CORS échoue-t-elle uniquement dans Firefox?

J'implémente CORS avec des informations d'identification et une demande de contrôle en amont et je ne comprends pas trop pourquoi cette demande de contrôle en amont échoue systématiquement dans Firefox 30, mais fonctionne dans Safari (7.0.2) et Chrome 35. Je pense que ce problème est différent de " Pourquoi la requête OPTIONS de contrôle en amont d'une requête CORS authentifiée fonctionne-t-elle dans Chrome mais pas dans Firefox? "Parce que je ne reçois pas de message 401, mais plutôt un message spécifique à CORS du client du navigateur:

"Demande d'origine croisée bloquée: la règle de même origine ne permet pas la lecture de la ressource distante à l'adresse http://myurl.dev.com . Cela peut être résolu en déplaçant la ressource dans le même domaine ou en activant CORS."

Sans montrer le code source, voici ce que je fais:

Sur le serveur:

En-têtes de réponse OPTIONS:

  • Access-Control-Allow-Origin: [[copier l'origine de la requête ici]]
  • Access-Control-Allow-Methods: "OPTIONS POST-GET"
  • En-têtes de contrôle d'accès autorisés: "X-Requested-With"
  • Contrôle d'accès, autorisation d'accès: "true"

En-têtes de la réponse POST:

  • Access-Control-Allow-Origin: [[copier l'origine de la requête ici]]
  • Contrôle d'accès, autorisation d'accès: "true"

Dans le client de navigation:

jQuery.ajax({
  url: requestUrl,
  type: 'POST',
  data: getData(),
  xhrFields: {
    withCredentials: true
  }
});

Selon les spécifications, cela déclenchera une demande de contrôle en amont OPTIONS qui doit avoir les en-têtes CORS dans sa réponse. J'ai lu les spécifications du W3C à plusieurs reprises et je ne peux pas identifier ce que je fais mal, si quelque chose se passe, dans cette réponse de contrôle en amont.

13
rq_

Notez que Firefox est le seul navigateur compatible ici. Si l'analyse de Access-Control-Allow-Methods échoue par https://fetch.spec.whatwg.org/#cors-preflight-fetch , une erreur réseau doit être renvoyée. Et selon le ABNF pour la valeur d'en-tête, il s'agit très certainement d'une valeur séparée par des virgules.

8
Anne

J'ai remarqué que lorsque vous envoyez une demande CORS (Cross Origin Resource Sharing) avec les cookies configurés, Firefox n'envoie pas les en-têtes de réponse requis.

Solution: 

La solution ci-dessous ajoute des en-têtes uniquement pour les demandes OPTIONS et accepte uniquement les demandes de example.com. Vous pouvez modifier l'implémentation pour d'autres méthodes de requête et hôtes attendus.

JS CODE

var xmlhttp = new XMLHttpRequest();
xmlhttp.withCredentials = true;

xmlhttp.onreadystatechange = function () {
    if (xmlhttp.readyState == XMLHttpRequest.DONE) {
        if (xmlhttp.status == 200) {
            success_callback(xmlhttp.responseText);
        } else {
            error_callback(xmlhttp.statusText);
        }
    }
};
xmlhttp.open("DELETE", url);
xmlhttp.send(null);

Lorsque vous envoyez une demande DELETE, le navigateur envoie une demande de pré-vol pour OPTIONS, qui attend Access-Control-Allow-Methods dans les en-têtes de réponse. Sur la base de cette valeur d'en-tête, la demande DELETE réelle est envoyée. Dans Firefox, lorsque vous envoyez une demande DELETE, les en-têtes de réponse de la demande de pré-vol n’ont pas les en-têtes prévus. Par conséquent, il ne parvient pas à envoyer la demande DELETE réelle.

Pour résoudre ce problème, utilisez la configuration du serveur NGINX ci-dessous.

NGINX CODE

#handle CORS requests by adding required headers
if ($http_Origin ~* .example.com) {
    set $cors "CORS-${request_method}";
}

if ($cors = "CORS-OPTIONS") {
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Headers' 'Content-Type';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
    add_header 'Access-Control-Allow-Origin' $http_Origin;
}

Bonne lecture sur CORS: https://www.html5rocks.com/fr/tutorials/cors/

0
Akshay Goyal