La redirection HTTP 302 vers une requête CORS est abandonnée par les navigateurs

je charge une page HTML avec du javascript du site A.

Javascript envoie une requête HTTP GET au site B.:

- le navigateur envoie la demande D'OPTIONS au site B

- le Site B répond à la demande D'OPTIONS

- le navigateur envoie alors la requête HTTP GET originale au site B

- le Site B répond avec HTTP 302 dont L'emplacement est défini au site C.

à ce point le navigateur s'arrête le traitement de la demande. Je m'attendais à ce qu'il envoie la requête D'OPTIONS HTTP au site C comme il l'a fait quand il a envoyé la requête au Site B. Mais il ne l'a pas fait. J'ai observé le même comportement sur Firefox et Chrome.

je voudrais comprendre pourquoi les navigateurs se comportent de cette façon. Je comprends qu'il devrait y avoir quelques vérifications ou redirections max pour empêcher les boucles mais pas limité 2 requêtes de redirection.

aussi pourquoi les informations d'en-tête ne sont pas envoyées au code Javascript pour que l'application peut faire quelque chose à ce sujet. Il est simplement abandonné par navigateur bien qu'il vous taquine en montrant la réponse HTTP 302 du site C avec L'URL de localisation dans la console de navigateur.

XMLHttpRequest ne peut pas charger https://siteB/... La requête a été redirigée vers'https://siteC/..', ce qui est refusé pour les demandes d'origine croisée qui nécessitent un vol avant.

toutes les idées sur la conception sont sincères apprécier.

Cordialement

17
demandé sur Manoj Saxena 2015-03-07 20:01:40

2 réponses

Eh bien, j'ai eu le même problème que vous, et malheureusement, ce comportement est normal, selon les spécifications du W3C

cette spécification décrit le comportement du navigateur en ce qui concerne CORS en tant qu'état machine, et si vous passez à l'étape 3 (Faire la demande réelle), elle indique clairement :

C'est la demande réelle. Appliquer les étapes faire une demande et observer les règles de demande ci-dessous en fait la demande.

si la réponse contient Code D'état HTTP de 301, 302, 303, 307, ou 308 Appliquer les étapes d'erreur cache et réseau.

donc si je comprends bien, on ne peut pas s'attendre à ce que le navigateur suive automatiquement la redirection en cas de CORS (soit-disant, comme L'OPTION a accordé l'accès à une autre ressource ? Mais alors pourquoi ne pas envoyer automatiquement une autre demande D'OPTION à cette ressource ?).

ce qui est pire, car les en-têtes de la réponse sont cachés par le navigateur après la redirection automatique échoué pour la raison ci-dessus, nous n'avons pas accès à l'en-tête Location pour traiter l'appel suivant à la bonne ressource nous-mêmes. Donc, il n'y a aucun moyen de récupérer la ressource réelle dans ce cas.

je considère que c'est un bug, mais je n'ai pas pu trouver un bon post sur le sujet sur le web.

une solution de rechange, si possible pour vous, est de ne pas faire une requête CORS mais plutôt d'utiliser une requête simple( selon les spécifications encore, comme un simple GET sans en-tête personnalisé), qui n'entraînera pas l'envoi de requêtes preflight : dans ce cas, la redirection fonctionne normalement (automatiquement suivie par le navigateur).

sinon, vous pourriez voir si vous pouvez ajuster votre serveur pour ne pas répondre 302 Dans le cas d'une requête de type CORS, mais plutôt répondre avec un code HTTP personnalisé que vous pouvez identifier dans votre client pour inclure l'emplacement de redirection dans le contenu de la réponse pour laisser votre client le suivre manuellement.

Si quelqu'un a des informations valides A propos de pourquoi ce comportement est, s'il vous plaît donnez votre contribution :-)

j'Espère que ça aide.

26
répondu Mathis Gardon 2015-05-12 13:29:21

Je ne suis pas sûr que ma réponse marcherait pour votre cas ou pas.

ma requête client est redirigée par cosign; par conséquent, j'ai l'url de cosign dans le contrôle D'accès-Allow-Origin. Et cela fonctionne pour moi. De plus, ajoutez les champs XHR aveccredentials dans le client AJAX.

 $.ajax( {url:url, success:function(result){   alert(result.toString()); } 
 ,xhrFields: {withCredentials: true}

et le serveur .NET a le SupportsCredentials = true

 [EnableCors(origins: "https://cosign_URL", headers: "*"
    , methods: "get,post", SupportsCredentials = true)]
-1
répondu Sinji Yang 2018-03-22 15:48:25