Origen <origin> no está permitido por Access-Control-Allow-Origin

184
XMLHttpRequest cannot load http://localhost:8080/api/test. Origin http://localhost:3000 is not allowed by Access-Control-Allow-Origin. 

Leí sobre las solicitudes ajax de dominio cruzado y entiendo el problema de seguridad subyacente. En mi caso, 2 servidores se ejecutan localmente y desean habilitar las solicitudes de dominio cruzado durante las pruebas.

localhost:8080 - Google Appengine dev server
localhost:3000 - Node.js server

Estoy emitiendo una solicitud ajax localhost:8080 - GAE servermientras mi página se carga desde el servidor de nodo. ¿Qué es lo más fácil y seguro? (No quiero iniciar Chrome con la disable-web-securityopción). Si tengo que cambiar 'Content-Type', ¿debería hacerlo en el servidor de nodo? ¿Cómo?

bsr
fuente
Puede encontrar una solución más rápida aquí: stackoverflow.com/a/21622564/4455570
Gabriel Wamunyu

Respuestas:

195

Como se ejecutan en diferentes puertos, son diferentes JavaScript origin. No importa que estén en la misma máquina / nombre de host.

Debe habilitar CORS en el servidor (localhost: 8080). Echa un vistazo a este sitio: http://enable-cors.org/

Todo lo que necesita hacer es agregar un encabezado HTTP al servidor:

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

O, por simplicidad:

Access-Control-Allow-Origin: *

Pensé que no use "*" si su servidor está tratando de configurar cookies y usted usa withCredentials = true

al responder a una solicitud con credenciales, el servidor debe especificar un dominio y no puede usar comodines.

Puedes leer más sobre withCredentialsaquí

Cohete Hazmat
fuente
si queremos agregar este encabezado a un HTML, ¿qué debemos hacer por él?
Azam Alvi
1
No pensé que ese puerto fuera necesario, pero si está utilizando un puerto no estándar como 3000, debe incluirlo en la política de CORS.
Michael Connor
44
Gracias por esta respuesta Solo quiero resaltar las implicaciones de seguridad de usar '*' como el valor aquí. Esto permite todos los orígenes: developer.mozilla.org/en-US/docs/Web/HTTP/Headers/… Parece que el primer ejemplo sería el mejor en términos de acceso mínimo. Detalles sobre cómo hacer esto con múltiples dominios aquí: stackoverflow.com/a/1850482/1566623
Christopher Kuttruff
14
En aras de la claridad, cuando se dice que necesita "agregar un encabezado HTTP al servidor", esto significa que el Access-Control-Allow-Originencabezado dado debe ser un encabezado agregado a las respuestas HTTP que envía el servidor. Este encabezado debe ser parte de la respuesta del servidor, no necesita ser parte de la solicitud del cliente . Específicamente, lo que sucede es antes de que el cliente haga la solicitud real que desea, el navegador envía una OPTIONSsolicitud antes y, si la respuesta del servidor a esa OPTIONSsolicitud no contiene el encabezado, el navegador no enviará su solicitud deseada.
AjaxLeung
1
Es importante leer los consejos relevantes para sus servidores de back-end en enable-cors.org.
Karlth
69

Si necesita una solución rápida en Chrome para solicitudes ajax, este complemento de Chrome le permite acceder automáticamente a cualquier sitio desde cualquier fuente agregando el encabezado de respuesta adecuado

Extensión de Chrome Permitir-Control-Permitir-Origen: *

Billy Baker
fuente
66
No sé por qué no recibes más votos a favor. Este es el menos intrusivo para el desarrollo en localhost con Chrome.
David Betz
definitivamente de acuerdo. Fácil de habilitar para el desarrollo localhost en un servidor remoto sin tener que cambiar la configuración del servidor remoto.
Jens Wegar
@DavidBetz: considerando que verificas la extensión y confías en ella, por supuesto;)
haylem
2
¡ESTO DEBE SER LA RESPUESTA SUPERIOR! Especialmente en lo que respecta a localhost.
Sr. Benedict
16
Si esta fuera una buena solución, CORS no se habría inventado en primer lugar. La aplicación de este encabezado a cualquier host deshabilita la protección CORS y lo expone a scripts maliciosos, no solo a los suyos. No se sorprenda si su cuenta bancaria está repentinamente vacía.
dolmen
54

Tienes que habilitar CORS para resolver esto

si su aplicación se crea con node.js simple

configurarlo en sus encabezados de respuesta como

var http = require('http');

http.createServer(function (request, response) {
response.writeHead(200, {
    'Content-Type': 'text/plain',
    'Access-Control-Allow-Origin' : '*',
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE'
});
response.end('Hello World\n');
}).listen(3000);

si su aplicación se crea con express framework

usar un middleware CORS como

var allowCrossDomain = function(req, res, next) {
    res.header('Access-Control-Allow-Origin', "*");
    res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
    res.header('Access-Control-Allow-Headers', 'Content-Type');
    next();
}

y aplicar a través de

app.configure(function() {
    app.use(allowCrossDomain);
    //some other code
});    

Aquí hay dos enlaces de referencia

  1. cómo-permitir-cors-en-express-nodejs
  2. dive-into-node-js-very-first-app #ver la sección Ajax
mithunsatheesh
fuente
¿puede especificar cómo usarlo config.allowedDomains? en mi caso, ¿qué uri debo poner allí?
bsr
@bsr: puede usar *o el specific domainque desea dar acceso.
mithunsatheesh
1
Entonces, ¿soy el único que app.configure()recibe no es un error de función?
Pramesh Bajracharya
@PrameshBajrachaya No incluí la parte "app.configure" - solo "app.use (allowCrossDomain)", y funcionó para mí.
Giorgos Sfikas
8

Acepto la respuesta de @Rocket Hazmat, ya que me llevó a la solución. De hecho, fue en el servidor GAE que necesitaba configurar el encabezado. Tuve que configurar estos

"Access-Control-Allow-Origin" -> "*"
"Access-Control-Allow-Headers" -> "Origin, X-Requested-With, Content-Type, Accept"

la configuración solo "Access-Control-Allow-Origin" dio error

Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers.

Además, si necesita enviar un token de autenticación, agréguelo también

"Access-Control-Allow-Credentials" -> "true"

Además, en el cliente, establezca withCredentials

esto hace que se envíen 2 solicitudes al servidor, una con OPTIONS. La cookie de autenticación no se envía con ella, por lo tanto, debe tratar la autenticación externa.

bsr
fuente
7

En router.js solo agregue el código antes de llamar a los métodos get / post. Funciona para mí sin errores.

//Importing modules @Brahmmeswar
const express = require('express');
const router = express.Router();

const Contact = require('../models/contacts');

router.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
  });
Brahmmeswara Rao Palepu
fuente
5

Estaba enfrentando un problema al llamar a un recurso de origen cruzado usando ajax desde Chrome.

He usado el nodo js y el servidor http local para implementar mi aplicación de nodo js.

Recibía una respuesta de error cuando accedo al recurso de origen cruzado

Encontré una solución en eso,

1) He agregado el siguiente código a mi archivo app.js

res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");

2) En mi página html llamada recurso de origen cruzado usando $.getJSON();

$.getJSON("http://localhost:3000/users", function (data) {
    alert("*******Success*********");
    var response=JSON.stringify(data);
    alert("success="+response);
    document.getElementById("employeeDetails").value=response;
});
Chaitanya
fuente
5

Si está utilizando express, puede usar el middleware cors de la siguiente manera:

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())
Akalanka Weerasooriya
fuente
3

Agregue esto a su servidor NodeJS debajo de las importaciones:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
Ryan Cocuzzo
fuente
3

Si obtuvo 403 después de eso, reduzca los filtros en la configuración de tomcat de WEB.XML a lo siguiente:

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
</filter>
Farbod Aprin
fuente
2

Finalmente obtuve la respuesta para apache Tomcat8

Tiene que editar el archivo tomcat web.xml.

probablemente estará dentro de la carpeta webapps,

sudo gedit /opt/tomcat/webapps/your_directory/WEB-INF/web.xml

encuéntralo y edítalo

<web-app>


<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
  <init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
  </init-param>
  <init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
  </init-param>
  <init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
  </init-param>
  <init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
  </init-param>
  <init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
  </init-param>
</filter>


<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>



</web-app>

Esto permitirá Access-Control-Allow-Origin a todos los hosts. Si necesita cambiarlo de todos los hosts a solo su host, puede editar el

<param-name>cors.allowed.origins</param-name>
<param-value>http://localhost:3000</param-value>

código anterior de * a su http: // your_public_IP o http://www.example.com

puede consultar aquí la documentación del filtro Tomcat

Gracias

Joseph sintoísta
fuente
1

Hola, esta es la forma de resolver el problema CORS en el nodo. Simplemente agregue estas líneas en el lado "api" del servidor en Node.js (o en el archivo del servidor), asegúrese de instalar "cors"

    const express = require('express');
    const app = express();
    app.use(express.json());
    var cors = require('cors');
    app.use(cors());
Saad Abbasi
fuente
0

use dataType: 'jsonp', funciona para mí.

   async function get_ajax_data(){

       var _reprojected_lat_lng = await $.ajax({

                                type: 'GET',

                                dataType: 'jsonp',

                                data: {},

                                url: _reprojection_url,

                                error: function (jqXHR, textStatus, errorThrown) {

                                    console.log(jqXHR)

                                },

                                success: function (data) {

                                    console.log(data);



                                    // note: data is already json type, you just specify dataType: jsonp

                                    return data;

                                }

                            });





 } // function               
hoogw
fuente
0

Para PHP, use esto para establecer encabezados.

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: PUT, GET, POST");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
Hamza Waleed
fuente
0
router.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "*");
res.header("Access-Control-Allow-Headers", "*");
next();});

agregue esto a sus rutas que está llamando desde el front-end. Por ejemplo, si solicita http: // localhost: 3000 / users / register , debe agregar este fragmento de código en su archivo .js de fondo que establece esta ruta.

Sujeewa K. Abeysinghe
fuente
0

En caso de que alguien busque la solución, si está utilizando express, esta es la solución rápida.

const express = require('express')
const cors = require('cors')
const app = express()

1) instalar cors usando npm npm install cors --save

2) importarlo [requerir] const cors = require('cors')

3) utilízalo como middleware app.use(cors())

para detalles de insatll y uso de cors . Eso es todo, con suerte funciona.

Badri Paudel
fuente