CORS mortel quand http: // localhost est l'origine

196

Je suis coincé avec ce problème CORS, même si j'ai défini le serveur (nginx / node.js) avec les en-têtes appropriés.

Je peux voir dans le volet Réseau Chrome -> En-têtes de réponse:

Access-Control-Allow-Origin:http://localhost

ce qui devrait faire l'affaire.

Voici le code que j'utilise maintenant pour tester:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
   console.log('xhr loaded');
};
xhr.open('GET', 'http://stackoverflow.com/');
xhr.send();

Je reçois

XMLHttpRequest ne peut pas charger http://stackoverflow.com/ . Origin http: // localhost n'est pas autorisé par Access-Control-Allow-Origin.

Je soupçonne que c'est un problème dans le script client et non dans la configuration du serveur ...

whadar
la source
46
Non, stackoverflow.com doit définir cet en-tête, pas vous. :X. Quel serait l'intérêt d'une même politique d'origine autrement.
Esailija le
3
Essayez d'accéder au serveur que vous avez configuré sans débordement de pile. ;)
Nek
DOH! Existe-t-il un moyen de dire à chrome (ou à un autre navigateur), d'obtenir la ressource même si l'en-tête est manquant lorsque mon origine est localhost?
whadar le
Exécutez vos codes dans Chrome (20.0.1132.57, Windows 7), fonctionne très bien.
imwilsonxu
1
Si vous utilisez localhost avec un port, cette réponse a fonctionné pour moi serverfault.com/a/673551/238261 .
Nelu le

Réponses:

245

Chrome ne prend pas en charge localhost pour les requêtes CORS (un bug ouvert en 2010, marqué WontFix en 2014).

Pour contourner cela, vous pouvez utiliser un domaine comme lvh.me(qui pointe à 127.0.0.1 tout comme localhost) ou démarrer chrome avec l' --disable-web-securityindicateur (en supposant que vous ne faites que tester).

Beau
la source
27
@greensuisse - il ne publie pas sur localhost. C'est la publication de localhost qui est le problème.
Cheeso
10
Ce bogue n'est pas valide (et a été marqué comme tel - crbug.com/67743#c17 ). Le commentaire d'Esailija est correct, ajouter ces en-têtes à localhost ne vous donnera pas accès par magie à tous les autres sites. C'est le site distant qui doit être servi avec ces en-têtes.
Rob W
11
Autre option: modifiez votre fichier hosts afin que local. [Mysite] .com pointe vers 127.0.0.1, puis autorisez votre fichier CORS *. [Mysite] .com
tom
6
J'ai rencontré le même problème avec FireFox. Je ne pouvais réussir que sur Edge! Belle publication cependant, fantastique! :)
Luis Gouveia
4
voir le commentaire de @ Molomby ci-dessous "Chrome 100% prend en charge les demandes cross-origin depuis et vers l'hôte local ..."
Anthony Johnston
58

Selon la réponse de @ Beau, Chrome ne prend pas en charge les requêtes CORS de l'hôte local, et il est peu probable qu'un changement dans ce sens.

J'utilise l' extension Allow-Control-Allow-Origin: * Chrome pour contourner ce problème. L'extension ajoutera les en-têtes HTTP nécessaires pour CORS:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: "GET, PUT, POST, DELETE, HEAD, OPTIONS"
Access-Control-Expose-Headers: <you can add values here>

Le code source est publié sur Github .

Notez que l'extension filtre toutes les URL par défaut. Cela peut casser certains sites Web (par exemple: Dropbox). Je l'ai modifié pour filtrer uniquement les URL de l' hôte local avec le filtre d'URL suivant

*://localhost:*/*
Hanxue
la source
18
Si vous lisez le problème des liens @beau vers, vous verrez que Chrome 100% prend en charge les demandes d'origine croisée vers et depuis l'hôte local. Le problème a été clos en 2014 car il n'a pas pu être reproduit. Le reste du bruit dans ce fil est des personnes avec des serveurs non d'origine mal configurés (comme avec la question d'origine ici).
Molomby
1
A travaillé comme du charme pour moi sur chrome
Aakash Sahai
4
Cette extension ne fonctionne pas avec Access-Control-Allow-Credentials: trueparce qu'il met Access-Control-Allow-Originà *et ayant à la fois trueet *est bloqué par les navigateurs. Si les informations d'identification sont vraies, vous devez utiliser une origine non générique. Je recommande Moesif Origins et CORS Changer Extension qui vous permet de changer les en-têtes comme vous le souhaitez.
Samuel le
1
@Chiwda, vous pouvez trouver ce qui précède et en charger plus ici: addons.mozilla.org/en-GB/firefox/search/…
redplanet le
20

Le vrai problème est que si nous définissons -Allow-toutes les demandes ( OPTIONS& POST), Chrome l'annulera. Le code suivant fonctionne pour moi avec POSTLocalHost avec Chrome

<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
    //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header("Access-Control-Allow-Origin: *");
    header('Access-Control-Allow-Credentials: true');    
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
}   
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
} 
?>
greensuisse
la source
15
OP utilise nginx / node.js. Not PHP
code_monk
5

Chrome fera très bien des demandes avec CORS depuis une localhostorigine. Ce n'est pas un problème avec Chrome.

La raison pour laquelle vous ne pouvez pas charger http://stackoverflow.comest que les en- Access-Control-Allow-Origintêtes ne permettaient pas votre localhostorigine.

Brad
la source
4

Aucune des extensions n'a fonctionné pour moi, j'ai donc installé un simple proxy local. Dans mon cas https://www.npmjs.com/package/local-cors-proxy C'est une configuration de 2 minutes:

(depuis leur site)

npm install -g local-cors-proxy

Point de terminaison d'API que nous voulons demander et qui présente des problèmes CORS: https://www.yourdomain.ie/movies/list

Démarrez le proxy: lcp --proxyUrl https://www.yourdomain.ie

Puis dans votre code client, nouveau point de terminaison d'API: http://localhost:8010/proxy/movies/list

Cela a fonctionné comme un charme pour moi: votre application appelle le proxy, qui appelle le serveur. Aucun problème CORS.

Daniel p
la source
3

Correction de l'extension Chrome rapide et sale:

Changeur Moesif Orign & CORS

Cependant, Chrome prend en charge les demandes d'origine croisée de localhost. Assurez-vous d'ajouter un en-tête pour Access-Control-Allow-Originpour localhost.

kaleazy
la source
J'ai ajouté cette extension à mon Opera et maintenant c'est f'd. Je ne peux jamais dire quand il est allumé et éteint alors j'utilise Firefox pour le travail. et l'opéra pour le développement. google suit ne l'aime pas, et d'autres choses non plus.
Maddocks
0

J'ai décidé de ne pas toucher les en-têtes et de faire une redirection côté serveur à la place et cela fonctionne comme un charme.

L'exemple ci-dessous concerne la version actuelle d'Angular (actuellement 9) et probablement tout autre framework utilisant des webpacks DevServer. Mais je pense que le même principe fonctionnera sur d'autres backends.

J'utilise donc la configuration suivante dans le fichier proxy.conf.json :

{
  "/api": {
    "target": "http://localhost:3000",
    "pathRewrite": {"^/api" : ""},
   "secure": false
 }
}

En cas d'Angular, je sers avec cette configuration:

$ ng serve -o --proxy-config=proxy.conf.json

Je préfère utiliser le proxy dans la commande serve, mais vous pouvez également mettre cette configuration dans angular.json comme ceci:

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "src/proxy.conf.json"
    },

Voir également:

https://www.techiediaries.com/fix-cors-with-angular-cli-proxy-configuration/

https://webpack.js.org/configuration/dev-server/#devserverproxy

Juri Sinitson
la source