Explicación del encabezado Access-Control-Allow-Origin: con un ejemplo de CORS

A menudo, al llamar a una API, es posible que vea un error en su consola que se parece a esto:

 Access to fetch at '//somesite.com' from origin '//yoursite.com' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value that is not equal to the supplied origin 

En esta publicación, aprenderemos por qué ocurre este error y cómo puede solucionarlo.

¿Qué es el Access-Control-Allow-Originencabezado?

Access-Control-Allow-Origines un encabezado CORS. CORS, o Cross Origin Resource Sharing, es un mecanismo para que los navegadores permitan que un sitio que se ejecuta en el origen A solicite recursos del origen B.

El origen no es solo el nombre de host, sino una combinación de puerto, nombre de host y esquema, como: //mysite.example.com:8080/

Aquí hay un ejemplo de dónde entra en acción esto:

  1. Tengo un origen A: //mysite.comy quiero obtener recursos del origen B : //yoursite.com.
  2. Para proteger su seguridad, el navegador no me permitirá acceder a los recursos de su sitio.com y bloqueará mi solicitud.
  3. Para permitir que el origen A acceda a sus recursos, su origen B deberá informar al navegador que puedo obtener recursos de su origen.

Aquí hay un ejemplo de Mozilla Developer Network que explica esto muy bien:

Con la ayuda de CORS, los navegadores permiten que los orígenes compartan recursos entre ellos.

Hay algunos encabezados que permiten compartir recursos entre orígenes, pero el principal es Access-Control-Allow-Origin. Esto le dice al navegador qué orígenes pueden recibir solicitudes de este servidor.

¿Quién necesita establecer Access-Control-Allow-Origin?

Para comprender quién debe configurar este encabezado, considere este escenario: está navegando en un sitio web que se usa para ver y escuchar canciones. El sitio web intenta establecer una conexión con su banco en segundo plano de forma maliciosa.

Entonces, ¿quién tiene la capacidad máxima para evitar que este sitio web malicioso robe sus datos del banco? ¡El Banco! Por lo tanto, el banco deberá proteger sus recursos configurando el Access-Control-Allow-Originencabezado como parte de la respuesta.

Solo recuerde: el origen responsable de servir los recursos deberá configurar este encabezado.

Cómo usar y cuándo pasar este encabezado

A continuación, se muestra un ejemplo de valores que puede establecer:

  1. Access-Control-Allow-Origin : * : Admite cualquier origen.
  2. Access-Control-Allow-Origin : //mysite.com : Permitir solicitudes solo de mysite.com.

Míralo en acción

Veamos un ejemplo. Puede consultar este código en mi repositorio de GitHub.

Vamos a construir un servidor en el origen A //localhost:8000que enviará una cadena de Hellosa un apipunto final. Vamos a llamar con este punto final creando un cliente en el origen B //localhost:3000y luego usaremos fetch para solicitar el recurso. Esperamos ver la cadena Hellopasada por el origen A en la consola del navegador del origen B.

Digamos que tenemos un origen //localhost:8000que sirve este recurso en el /apipunto final. El servidor envía una respuesta con el encabezado Access-Control-Allow-Origin.

const express = require("express"); const app = express(); const port = process.env.SERVER_PORT || 8000; // Add Access Control Allow Origin headers app.use((req, res, next) => { res.setHeader("Access-Control-Allow-Origin", "//yoursite.com"); res.header( "Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept" ); next(); }); app.get("/api", (req, res) => { res.json("Hello"); }); app.listen(port, () => console.log(`Listening on port ${port}`)); 

En el lado del cliente, puede llamar a este punto final llamando fetchasí:

fetch('//localhost:8000/api') .then(res => res.json()) .then(res => console.log(res)); 

Ahora abra la consola de su navegador para ver el resultado.

Dado que el encabezado está configurado actualmente para permitir el acceso solo desde //yoursite.com, el navegador bloqueará el acceso al recurso y verá un error en su consola.

Ahora, para solucionar este problema, cambie los encabezados a esto:

 res.setHeader("Access-Control-Allow-Origin", "*"); 

Verifique la consola de su navegador y ahora podrá ver la cadena Hello.

¿Interesado en más tutoriales y JSBytes de mi parte? Inscríbete a mi boletín de noticias.