La requête CORS échoue dans Chrome uniquement si des en-têtes sont disponibles.

J’essaie d’envoyer une simple requête CORS au serveur d’applications externe qui utilise la clé de session pour l’autorisation.

$.ajax({ type: "GET", url: "https://192.168.1.72:8442/api/file/", headers: {"Authorization": "3238562439e44fcab4036a24a1e6b0fb"} }); 

Cela fonctionne bien dans Firefox 18, Opera 12.12 et Rekonq 2.0 (utilise également WebKit) mais ne fonctionne pas dans Google Chrome (versions 21 et 24 essayées). Dans Google Chrome, il indique que le chargement des ressources dans OPTIONS a échoué dans Network Inspector et que le serveur d’applications ne reçoit aucune demande. J’ai essayé jQuery 1.8.3 et 1.9.0.

 Request URL:https://192.168.1.72:8442/api/file/ Request Headers Access-Control-Request-Headers:accept, authorization, origin Access-Control-Request-Method:GET Cache-Control:no-cache Origin:https://192.168.1.72:8480 Pragma:no-cache 

Si je supprime les en-têtes de la demande, je reçois également 401 également dans Google Chrome et celui-ci est en mesure d’accéder à la ressource en cas d’autorisation est désactivé sur le serveur d’applications. Peu importe les en-têtes envoyés. Seul l’en-tête que je peux envoyer est {“Content-Type”: “plain / text”}. Tous les autres noms / valeurs d’en-tête génèrent une erreur dans Google Chrome mais fonctionnent dans tous les navigateurs que j’ai mentionnés ci-dessus.

Pourquoi Google Chrome ne gère-t-il pas les en-têtes dans les demandes CORS?

C’est un bug dans Google Chrome: http://code.google.com/p/chromium/issues/detail?id=96007 .

J’utilise un certificate auto-signé sur mon serveur api et cela semble être le problème. J’ai constaté que si je lance Google Chrome avec l’ --disable-web-security , alors CORS avec en-têtes de requête fonctionne. Sans --disable-web-security je peux envoyer des demandes CORS au serveur api auto-signé mais je ne peux append aucun en-tête (sauf Content-Type).

J’ai trouvé que Access-Control-Allow-Headers: * devrait être défini UNIQUEMENT pour la demande “OPTIONS”. Si vous le renvoyez pour une demande POST, le navigateur annule la demande (au moins pour chrome).

Le code PHP suivant fonctionne pour moi

 // Allow CORS header("Access-Control-Allow-Origin: *"); header('Access-Control-Allow-Credentials: true'); header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); // Access-Control headers are received during OPTIONS requests if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { header("Access-Control-Allow-Headers: *"); } 

J’ai trouvé des questions similaires avec des réponses trompeuses: – Le fil du serveur indique qu’il s’agit d’un bogue de chrome datant de 2 ans: Access-Control-Allow-Headers ne correspond pas à localhost. C’est faux: je peux utiliser CORS sur mon serveur local avec Post normalement – Access-Control-Allow-Headers accepte les caractères génériques. C’est également faux, le joker fonctionne pour moi (j’ai testé uniquement avec Chrome)

Cela me prend une demi-journée pour comprendre le problème.

Code heureux

Côté serveur : le serveur doit définir l’en-tête “Access-Control-Allow-Credentials” ainsi que les en-têtes autorisés dans “Access-Control-Allow-Headers”.

Côté client : vous pouvez définir xhrFields dans $ .ajax () au lieu de transmettre explicitement l’en-tête Auth.

 xhrFields: { withCredentials: true } 

Plus de détails ici .