CORS mortal cuando http: // localhost es el origen

186

Estoy atrapado con este problema CORS, aunque configuré el servidor (nginx / node.js) con los encabezados apropiados.

Puedo ver en el panel Red de Chrome -> Encabezados de respuesta:

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

que debería hacer el truco.

Aquí está el código que ahora uso para probar:

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

yo obtengo

XMLHttpRequest no puede cargar http://stackoverflow.com/ . Origen http: // localhost no está permitido por Access-Control-Allow-Origin.

Sospecho que es un problema en el script del cliente y no en la configuración del servidor ...

whadar
fuente
44
No, stackoverflow.com necesita establecer este encabezado, no tú. :X. Cuál sería el punto de la misma política de origen de lo contrario.
Esailija
3
Intente acceder al servidor que ha configurado, no al desbordamiento de pila. ;)
Nek
DOH! ¿Hay alguna manera de decirle a Chrome (u otro navegador) que obtenga el recurso incluso si falta el encabezado cuando mi origen es localhost?
whadar
Ejecute sus códigos en Chrome (20.0.1132.57, Windows 7), funciona bien.
imwilsonxu
1
Si está utilizando localhost con un puerto, esta respuesta funcionó para mí serverfault.com/a/673551/238261 .
Nelu

Respuestas:

230

Chrome no admite localhost para solicitudes CORS (un error abierto en 2010, marcado WontFix en 2014).

Para evitar esto, puede usar un dominio como lvh.me(que apunta a 127.0.0.1 como localhost) o iniciar Chrome con la --disable-web-securitybandera (suponiendo que solo esté probando).

Galán
fuente
24
@greensuisse: no se publica en localhost. Está publicando desde localhost que es el problema.
Cheeso
9
Ese error no es válido (y se ha marcado como tal: crbug.com/67743#c17 ). El comentario de Esailija es correcto, agregar estos encabezados a localhost no le dará mágicamente acceso a todos los demás sitios. Es el sitio remoto que necesita ser atendido con estos encabezados.
Rob W
22
Acabo de pasar 2 horas probando en Chrome para darme cuenta de que funciona perfectamente bien en Firefox ..Grrrr...
FloatingRock
11
Otra opción: edite su archivo de hosts para que local. [Mysite] .com apunte a 127.0.0.1, luego haga que su archivo CORS permita *. [Mysite] .com
tom
66
Me enfrenté al mismo problema con Firefox. ¡Solo pude hacerlo en Edge! Buena publicación, ¡fantástico! :)
Luis Gouveia
54

Según la respuesta de @ Beau, Chrome no admite las solicitudes locales de CORS, y es poco probable que haya algún cambio en esta dirección.

Utilizo la extensión de Chrome Allow-Control-Allow-Origin: * para solucionar este problema. La extensión agregará los encabezados HTTP necesarios para CORS:

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

El código fuente se publica en Github .

Tenga en cuenta que la extensión filtra todas las URL de forma predeterminada. Esto puede romper algunos sitios web (por ejemplo: Dropbox). Lo he cambiado para filtrar solo las URL de host local con el siguiente filtro de URL

*://localhost:*/*
Hanxue
fuente
14
Si lees el problema @beau links, verás que Chrome 100% admite solicitudes de origen cruzado hacia y desde localhost. El problema se cerró en 2014 porque no se pudo reproducir. El resto del ruido en ese hilo son personas con servidores no de origen mal configurados (como con la pregunta original aquí).
Molomby
1
Trabajó como encanto para mí en el cromo
Aakash Sahai
3
Esta extensión no funciona con Access-Control-Allow-Credentials: trueporque establece Access-Control-Allow-Originque *tengan las dos truey *es bloqueada por los navegadores. Si usa credenciales verdaderas, debe usar un origen que no sea comodín. Recomiendo Moesif Origins y CORS Changer Extension, que te permite cambiar los encabezados como quieras.
Samuel
Tal vez estoy haciendo algo mal, pero esta extensión ya no parece funcionar para mí.
James Parker
19

El verdadero problema es que si configuramos -Allow-todas las solicitudes ( OPTIONS& POST), Chrome la cancelará. El siguiente código funciona para mí con POSTLocalHost con 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
fuente
15
OP está usando nginx / node.js. No PHP
code_monk
4

Chrome hará solicitudes con CORS desde un localhostorigen muy bien. Esto no es un problema con Chrome.

La razón por la que no puede cargar http://stackoverflow.comes que los Access-Control-Allow-Originencabezados no permitían su localhostorigen.

Puntilla
fuente
2

Corrección rápida y sucia de la extensión de Chrome:

Cambiador Moesif Orign & CORS

Sin embargo, Chrome admite solicitudes de origen cruzado de localhost. Asegúrese de agregar un encabezado Access-Control-Allow-Originpara localhost.

kaleazy
fuente
Agregué esta extensión a mi Opera y ahora está activada. Nunca puedo decir cuándo está encendido y apagado, así que uso Firefox para el trabajo. y ópera para el desarrollo. google suit no le gusta, y otras cosas tampoco.
Maddocks
1

Ninguna de las extensiones funcionó para mí, así que instalé un proxy local simple. En mi caso https://www.npmjs.com/package/local-cors-proxy Es una configuración de 2 minutos:

(de su sitio)

npm install -g local-cors-proxy

Punto final de API que queremos solicitar que tenga problemas CORS: https://www.yourdomain.ie/movies/list

Proxy de inicio: lcp --proxyUrl https://www.yourdomain.ie

Luego, en su código de cliente, nuevo punto final de API: http://localhost:8010/proxy/movies/list

Para mí funcionó a las mil maravillas: su aplicación llama al proxy, quien llama al servidor. Cero problemas CORS.

daniel p
fuente
0

Decidí no tocar los encabezados y hacer una redirección en el lado del servidor, y funciona como un encanto.

El siguiente ejemplo es para la versión actual de Angular (actualmente 9) y probablemente para cualquier otro marco que use paquetes web DevServer. Pero creo que el mismo principio funcionará en otros backends.

Entonces uso la siguiente configuración en el archivo proxy.conf.json :

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

En caso de Angular, sirvo con esa configuración:

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

Prefiero usar el proxy en el comando de servicio, pero también puede poner esta configuración en angular.json de esta manera:

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

Ver también:

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

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

Juri Sinitson
fuente