Saltar al contenido

No hay un encabezado ‘Access-Control-Allow-Origin’ presente en el recurso solicitado, cuando se intenta obtener datos de una API REST

Hola usuario de nuestra página web, hemos encontrado la solución a lo que necesitas, desplázate y la encontrarás aquí.

Solución:

Esta respuesta cubre mucho terreno, por lo que se divide en tres partes:

  • Cómo usar un proxy CORS para moverse “Sin encabezado Access-Control-Allow-Origin” problemas
  • Cómo evitar la verificación previa de CORS
  • Como arreglar “El encabezado Access-Control-Allow-Origin no debe ser comodín” problemas

Cómo utilizar un proxy CORS para evitar “Sin encabezado Access-Control-Allow-Origin” problemas

Si no controla el servidor al que su código de interfaz está enviando una solicitud, y el problema con la respuesta de ese servidor es solo la falta de lo necesario Access-Control-Allow-Origin encabezado, aún puede hacer que las cosas funcionen, haciendo la solicitud a través de un proxy CORS.

Puede ejecutar fácilmente su propio proxy utilizando el código de https://github.com/Rob–W/cors-anywhere/.
También puede implementar fácilmente su propio proxy en Heroku en solo 2-3 minutos, con 5 comandos:

git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master

Después de ejecutar esos comandos, terminará con su propio servidor CORS Anywhere ejecutándose en, por ejemplo, https://cryptic-headland-94862.herokuapp.com/.

Ahora, anteponga la URL de su solicitud con la URL de su proxy:

https://cryptic-headland-94862.herokuapp.com/https://example.com

Agregar la URL del proxy como prefijo hace que la solicitud se realice a través de su proxy, que luego:

  1. Reenvía la solicitud a https://example.com.
  2. Recibe la respuesta de https://example.com.
  3. Agrega el Access-Control-Allow-Origin encabezado a la respuesta.
  4. Pasa esa respuesta, con ese encabezado agregado, de vuelta al código de interfaz solicitante.

Luego, el navegador permite que el código de la interfaz acceda a la respuesta, porque esa respuesta con el Access-Control-Allow-Origin El encabezado de respuesta es lo que ve el navegador.

Esto funciona incluso si la solicitud es una que hace que los navegadores realicen una verificación previa de CORS OPTIONS solicitud, porque en ese caso, el proxy también devuelve el Access-Control-Allow-Headers y Access-Control-Allow-Methods encabezados necesarios para que la verificación previa sea exitosa.


Cómo evitar la verificación previa de CORS

El código de la pregunta activa una verificación previa de CORS, ya que envía una Authorization encabezamiento.

https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Preflighted_requests

Incluso sin eso, el Content-Type: application/json El encabezado también desencadenaría una verificación previa.

Qué significa “verificación previa”: antes de que el navegador intente POST en el código de la pregunta, primero enviará un OPTIONS solicitud al servidor: para determinar si el servidor está optando por recibir un origen cruzado POST que tiene Authorization y Content-Type: application/json encabezados.

Funciona bastante bien con un pequeño script curl: obtengo mis datos.

Para probar correctamente con curl, debes emular la verificación previa OPTIONS solicitud que envía el navegador:

curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" 
    -H 'Access-Control-Request-Method: POST' 
    -H 'Access-Control-Request-Headers: Content-Type, Authorization' 
    "https://the.sign_in.url"

…con https://the.sign_in.url reemplazado por lo que sea tu actual sign_in URL es.

La respuesta que el navegador necesita ver de eso OPTIONS la solicitud debe tener encabezados como este:

Access-Control-Allow-Origin:  http://127.0.0.1:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type, Authorization

Si el OPTIONS la respuesta no incluye esos encabezados, entonces el navegador se detendrá allí mismo y ni siquiera intentará enviar el POST solicitud. Además, el código de estado HTTP para la respuesta debe ser 2xx, normalmente 200 o 204. Si se trata de cualquier otro código de estado, el navegador se detendrá allí mismo.

El servidor en la pregunta está respondiendo a la OPTIONS solicitud con un código de estado 501, lo que aparentemente significa que está tratando de indicar que no implementa el soporte para OPTIONS peticiones. Otros servidores suelen responder con un código de estado 405 “Método no permitido” en este caso.

Entonces nunca podrás hacer POST solicita directamente a ese servidor desde su código JavaScript frontend si el servidor responde a eso OPTIONS Solicite con un 405 o 501 o cualquier otra cosa que no sea un 200 o 204 o si no responde con los encabezados de respuesta necesarios.

La forma de evitar activar una verificación previa para el caso en la pregunta sería:

  • si el servidor no requirió un Authorization encabezado de la solicitud, pero en su lugar, por ejemplo, se basó en los datos de autenticación incrustados en el cuerpo del POST solicitud o como parámetro de consulta
  • si el servidor no requirió el POST cuerpo para tener un Content-Type: application/json tipo de medio, pero en su lugar aceptó el POST cuerpo como application/x-www-form-urlencoded con un parámetro llamado json (o lo que sea) cuyo valor son los datos JSON

Como arreglar “El encabezado Access-Control-Allow-Origin no debe ser comodín” problemas

Recibo otro mensaje de error:

El valor del encabezado ‘Access-Control-Allow-Origin’ en la respuesta no debe ser el comodín ‘*’ cuando el modo de credenciales de la solicitud es ‘incluir’. Por lo tanto, no se permite el acceso al origen ‘http://127.0.0.1:3000’. El modo de credenciales de las solicitudes iniciadas por XMLHttpRequest está controlado por el atributo withCredentials.

Para una solicitud que incluye credenciales, los navegadores no permitirán que su código JavaScript de frontend acceda a la respuesta si el valor de la Access-Control-Allow-Origin el encabezado de respuesta es *. En cambio, el valor en ese caso debe coincidir exactamente con el origen de su código de interfaz, http://127.0.0.1:3000.

Ver Solicitudes con credenciales y comodines en el artículo de MDN HTTP Access Control (CORS).

Si controla el servidor al que está enviando la solicitud, entonces una forma común de lidiar con este caso es configurar el servidor para que tome el valor de la Origin encabezado de solicitud, y repetirlo / reflejarlo en el valor de la Access-Control-Allow-Origin encabezado de respuesta; por ejemplo, con nginx:

add_header Access-Control-Allow-Origin $http_origin

Pero eso es solo un ejemplo; otros sistemas de servidor (web) proporcionan formas similares de hacer eco de los valores de origen.


Estoy usando Chrome. También intenté usar ese complemento CORS de Chrome

Ese complemento de Chrome CORS aparentemente simplemente inyecta de manera simple un Access-Control-Allow-Origin: * encabezado en la respuesta que ve el navegador. Si el complemento fuera más inteligente, lo que estaría haciendo es establecer el valor de esa falsificación Access-Control-Allow-Origin encabezado de respuesta al origen real de su código JavaScript frontend, http://127.0.0.1:3000.

Así que evita usar ese complemento, incluso para realizar pruebas. Es solo una distracción. Para probar qué respuestas obtiene del servidor sin que el navegador las filtre, es mejor que use curl -H como anteriormente.


En cuanto al código JavaScript frontend para el fetch(…) solicitud en la pregunta:

headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');

Elimina esas líneas. los Access-Control-Allow-* los encabezados son respuesta encabezados. Nunca querrás enviarlos en una solicitud. El único efecto que tendrá es activar un navegador para realizar una verificación previa.

Este error ocurre cuando la URL del cliente y la URL del servidor no coinciden, incluido el número de puerto. En este caso, debe habilitar su servicio para CORS, que es el intercambio de recursos de origen cruzado.

Si está alojando un servicio Spring REST, puede encontrarlo en la publicación del blog Soporte CORS en Spring Framework.

Si está alojando un servicio utilizando un servidor Node.js, entonces

  1. Detenga el servidor Node.js.
  2. npm install cors --save
  3. Agregue las siguientes líneas a su server.js

    var cors = require('cors')
    
    app.use(cors()) // Use this after the variable declaration
    

El problema surgió porque agregó el siguiente código como solicitud encabezado en su interfaz:

headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');

Esos encabezados pertenecen a respuesta, no solicitud. Entonces retirar ellos, incluida la línea:

headers.append('GET', 'POST', 'OPTIONS');

Tu solicitud tuvo 'Content-Type: application/json', por lo tanto, desencadenó lo que se llama Preflight CORS. Esto provocó que el navegador enviara la solicitud con el método OPTIONS. Consulte Preflight de CORS para obtener información detallada.

Por lo tanto en tu back-end, debe manejar esta solicitud de verificación previa devolviendo los encabezados de respuesta que incluyen:

Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, OPTIONS
Access-Control-Allow-Headers : Origin, Content-Type, Accept

Por supuesto, la sintaxis real depende del lenguaje de programación que use para su back-end.

En su interfaz, debería ser así:

function performSignIn() 
    let headers = new Headers();

    headers.append('Content-Type', 'application/json');
    headers.append('Accept', 'application/json');
    headers.append('Authorization', 'Basic ' + base64.encode(username + ":" +  password));
    headers.append('Origin','http://localhost:3000');

    fetch(sign_in, 
        mode: 'cors',
        credentials: 'include',
        method: 'POST',
        headers: headers
    )
    .then(response => response.json())
    .then(json => console.log(json))
    .catch(error => console.log('Authorization failed : ' + error.message));

Recuerda algo, que tienes permiso de interpretar .

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *