Tengo un servidor web de nodo (express) ejecutándose en el puerto 6000.

Cuando se invoca http://localhost:6000/, index.html se sirve al cliente que tiene un script, logic.js que se ejecuta:

var xhr = new XMLHttpRequest();
var url = 'http://localhost:4000/endpoint';
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/json');
xhr.onreadystatechange = function() {
  if (xhr.readyState === 4 && xhr.status === 200) {
    console.log('endpoint');
    callback(xhr.responseText);
  }
};
xhr.send(JSON.stringify({'key': 'value'}));

Hay otro servidor express ejecutándose en el puerto 4000.

El servidor configura un punto final que simplemente devuelve lo que envió el cuerpo de la solicitud:

app.route('/segment')
  .post(bodyParser.json(), function(req, res) {
  res.set('Access-Control-Allow-Origin', '*');
  res.send(req.body);
});

Cuando accedo a http://localhost:6000/, veo esto en la consola del navegador:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:4100/segment. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing)

¿Hay alguna forma de evitar esto durante la creación de prototipos?

0
bobbyrne01 16 feb. 2017 a las 13:15

3 respuestas

La mejor respuesta

Su punto final probablemente no sirva el método HTTP OPTIONS que utilizan los navegadores para verificar los encabezados CORS (antes de que realicen la solicitud real).

Si necesita diferentes encabezados CORS en el desarrollo y en la producción, creo que la mejor manera es agregar una nueva opción de configuración de back-end con el valor de los orígenes permitidos y servirlos desde algún filtro de respuesta global.

4
Ján Halaša 16 feb. 2017 a las 10:29

Aquí hay algunas maneras de resolver este problema:

Mejor: encabezado CORS (requiere cambios en el servidor)

CORS (Cross-Origin Resource Sharing) es una forma para que el servidor diga "Aceptaré su solicitud, a pesar de que usted vino de un origen diferente". Esto requiere la cooperación del servidor, por lo que si no puede modificar el servidor (por ejemplo, si está utilizando una API externa), este enfoque no funcionará.

Modifique el servidor para agregar el encabezado Access-Control-Allow-Origin: * para habilitar solicitudes de origen cruzado desde cualquier lugar (o especifique un dominio en lugar de *). Esto debería solucionar tu problema.

Segunda opción: servidor proxy

Si no puede modificar el servidor, puede ejecutar su propio proxy. Y este proxy puede devolver el encabezado Access-Control-Allow-Origin si no está en el mismo origen que su página.

En lugar de enviar solicitudes de API a algún servidor remoto, realizará solicitudes a su proxy, que las reenviará al servidor remoto. Aquí hay algunas opciones de proxy.

Tercera opción: JSONP (requiere soporte del servidor)

Si CORS y el servidor proxy no funcionan para usted, JSONP puede ayudarlo. Básicamente, realiza una solicitud GET con un parámetro de devolución de llamada:

(get) http://api.example.com/endpoint?callback=foo El servidor envolverá la respuesta JSON en una llamada de función a su devolución de llamada, donde puede manejarla:

Foo ({"your": "json", here: true}) Hay algunas desventajas, en particular que JSONP solo admite solicitudes GET y que aún necesita un servidor cooperativo.

1
Amit Kumar Verma 16 feb. 2017 a las 10:23

Ha configurado xhr.setRequestHeader('Content-type', 'application/json');, por lo que esta es una solicitud con verificación previa (regla general: un tipo de contenido que no sea un valor válido para el atributo enctype de un formulario HTML activará una solicitud con verificación previa).

Su código del lado del servidor solo establece el encabezado Access-Control-Allow-Origin en respuesta a las solicitudes POST. También debe escribir el código del lado del servidor para responder a la solicitud OPTIONS de verificación previa.

1
Quentin 16 feb. 2017 a las 10:21