logo

Extra Block Types (EBT) - Nueva experiencia con Layout Builder❗

Extra Block Types (EBT): tipos de bloques con estilo y personalizables: Presentaciones de diapositivas, Pestañas, Tarjetas, Acordeones y muchos más. Configuraciones integradas para fondo, DOM Box y plugins de JavaScript. Experimenta hoy el futuro de la construcción de diseños.

Módulos de demostración EBT Descargar módulos EBT

❗Extra Paragraph Types (EPT) - Nueva experiencia con Paragraphs

Extra Paragraph Types (EPT): conjunto de módulos basado en párrafos de forma análoga.

Módulos de demostración EPT Descargar módulos EPT

Scroll

CORS en React: qué es, por qué es importante y cómo habilitarlo

18/05/2025, by Ivan

Comprendiendo CORS en React

CORS ha sido durante mucho tiempo una fuente de confusión—y frustración—para los desarrolladores, especialmente para quienes están comenzando. El concepto puede ser difícil de entender, particularmente cuando creas aplicaciones de una sola página (SPAs) con frameworks como React, Angular o Vue y necesitas interactuar con APIs de terceros.

En esta guía, te ayudaré a entender CORS desde cero. Construiremos una app React sencilla junto con un servidor Express para ilustrar qué desencadena los errores de CORS y por qué suceden. Más importante aún, te mostraré diferentes formas de resolver estos problemas—tanto en general como específicamente dentro de un entorno React.


¿Qué es CORS?

CORS, o Cross-Origin Resource Sharing (Compartición de Recursos de Origen Cruzado), es un protocolo que regula cómo las aplicaciones web solicitan recursos a servidores alojados en orígenes diferentes. Así como HTTPS define reglas para la comunicación segura, CORS establece las reglas para las solicitudes de origen cruzado.

Las aplicaciones web modernas suelen estar divididas en dos partes clave: el cliente (el frontend que se ejecuta en tu navegador) y el servidor (normalmente una API o servicio backend). El cliente envía solicitudes al servidor—por ejemplo, para obtener datos—y el servidor devuelve una respuesta. CORS entra en juego cuando estas dos partes viven en dominios, puertos o protocolos distintos.

CORS localhost
Request to localhost.

Por qué esta arquitectura es tan común

Esta arquitectura desacoplada—donde el frontend y el backend se desarrollan y despliegan como aplicaciones separadas—es cada vez más popular. Una gran ventaja es la flexibilidad: tu backend puede servir a múltiples tipos de clientes, incluyendo apps web, interfaces de escritorio, apps móviles o incluso dispositivos IoT. Cada cliente puede consumir las mismas APIs sin estar acoplado a la capa de presentación.


La política de mismo origen y las solicitudes de origen cruzado

Como el cliente y el servidor son aplicaciones separadas, normalmente se alojan en dominios, puertos o protocolos diferentes. Esto significa que incluso cuando tu propio frontend intenta comunicarse con tu propio backend, el navegador puede tratar la solicitud como de origen cruzado.

Esto es aún más común al trabajar con servicios de terceros—para autenticación, analíticas, pasarelas de pago y más. En todos estos casos, tu frontend debe interactuar con un origen diferente enviando solicitudes HTTP.

Y aquí está el detalle: los navegadores modernos aplican una función de seguridad llamada Política de mismo origen (Same-Origin Policy, SOP), que restringe cómo los scripts de un origen pueden interactuar con recursos de otro. Ahí es donde CORS entra en acción: es el mecanismo que permite de forma segura esas solicitudes de origen cruzado.

CORS settings
Response from Server to Client from the same Origin

¿Por qué los navegadores bloquean solicitudes de origen cruzado?

Cuando tu aplicación web intenta solicitar un recurso de un origen diferente—como otro dominio, puerto o protocolo—el navegador aplica una función de seguridad llamada Política de mismo origen (SOP). Esta política está diseñada para evitar que sitios maliciosos accedan a datos sensibles en otro origen sin permiso.

Históricamente, esto ha hecho la web mucho más segura. Por ejemplo, un script que se ejecuta en xyz.com no podría obtener silenciosamente datos personales de abcbank.com, protegiendo a los usuarios de ataques de tipo cross-site. Sin embargo, la política de mismo origen también bloquea casos legítimos—como cuando tu app React en localhost:3000 intenta obtener datos de una API en localhost:8080 o de un servicio externo.


Entra CORS: la solución a las restricciones de SOP

Aquí es donde CORS (Cross-Origin Resource Sharing) interviene.

CORS es un protocolo que relaja la política de mismo origen bajo condiciones controladas. Permite que los servidores indiquen—mediante encabezados HTTP específicos—que ciertas solicitudes de origen cruzado son seguras y están permitidas.

Así que cuando tu aplicación cliente hace una solicitud a un origen diferente, el servidor puede responder con un conjunto especial de encabezados CORS. Estos encabezados actúan como un “permiso” que le dice al navegador: “Esta solicitud de origen cruzado está permitida.” Como resultado, tu navegador ya no bloquea la respuesta, y el recurso se comparte exitosamente.

Get response with CORS
Client-server request response with CORS enabled.

¿Qué pasa cuando CORS está habilitado?

Cuando tu navegador detecta los encabezados CORS en la respuesta del servidor, permite que tu aplicación acceda a los datos—aunque el origen de la solicitud sea distinto. Esa es la esencia de CORS: acceso controlado a recursos entre orígenes.

Ahora que tienes una base sólida sobre qué es CORS y por qué se necesita, pasemos a un ejemplo práctico para verlo en acción. Si quieres profundizar más, puedes revisar esta guía detallada de CORS para información adicional.


🛠️ Paso 1: Crea un servidor Express con endpoints API

Para demostrar cómo funciona CORS, necesitamos:

  • Un cliente (hecho con React) que haga solicitudes HTTP

  • Un servidor (hecho con Express) que exponga endpoints API para responder a esas solicitudes

⚠️ Para desencadenar un escenario real de CORS, el cliente y el servidor deben ejecutarse en orígenes diferentes—por ejemplo, puertos distintos como localhost:3000 y localhost:8080.


🧱 Configura el servidor

Comencemos creando un servidor Express básico.

  1. Crea la carpeta del proyecto:

mkdir cors-server && cd cors-server
  1. Inicializa un nuevo proyecto Node.js:

npm init -y

Esto crea un archivo package.json con valores por defecto.

  1. Instala Express:

npm install express
  1. Crea el archivo principal de la app:

Crea un archivo llamado app.js en el directorio raíz y agrega el siguiente código:

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

app.get('/', (req, res) => {
  res.send('Welcome to CORS server 😁');
});

app.get('/cors', (req, res) => {
  res.send('This has CORS enabled 🎈');
});

app.listen(8080, () => {
  console.log('Listening on port 8080');
});

Este es un servidor Express mínimo con dos endpoints:

  • / devuelve un mensaje de bienvenida.

  • /cors simula un endpoint de recurso que podrías consultar desde tu app React.

  1. Ejecuta el servidor:

node app

Una vez que inicie, visita http://localhost:8080/ en tu navegador y deberías ver:

Welcome to CORS server 😁

Y si visitas http://localhost:8080/cors, deberías ver algo así:

Express Server Endpoint /cors.
Express Server Endpoint /cors.

⚛️ Paso 2: Configura la app React

Ahora que nuestro servidor Express está en funcionamiento, es momento de crear una app React sencilla para hacer solicitudes HTTP a ese servidor—y provocar intencionalmente un error CORS para aprender cómo arreglarlo.


📦 Crea un nuevo proyecto React

En un directorio separado del servidor, ejecuta el siguiente comando:

npx create-react-app react-cors-guide

Esto creará una app React básica en una carpeta llamada react-cors-guide.

Cuando termine, navega al directorio del proyecto y abre el archivo src/App.js. Reemplaza su contenido con el siguiente código:

import { useEffect } from 'react';
import './App.css';

function App() {
  const makeAPICall = async () => {
    try {
      const response = await fetch('http://localhost:8080/', { mode: 'cors' });
      const data = await response.json();
      console.log({ data });
    } catch (error) {
      console.error('CORS error:', error);
    }
  };

  useEffect(() => {
    makeAPICall();
  }, []);

  return (
    <div className="App">
      <h1>React CORS Guide</h1>
    </div>
  );
}

export default App;


🧠 ¿Qué sucede aquí?

  • Definimos una función makeAPICall que hace una solicitud GET a http://localhost:8080/ usando la Fetch API.

  • La opción { mode: 'cors' } le dice explícitamente al navegador que esta es una solicitud de origen cruzado.

  • El hook useEffect asegura que la solicitud se realice apenas se monte el componente <App />.


🔥 Espera un error de CORS

Si ejecutas la app React con:

npm start

Y revisas la consola del desarrollador del navegador, probablemente verás un error de CORS parecido a este:

Access to fetch at 'http://localhost:8080/' from origin 'http://localhost:3000' has been blocked by CORS policy.

Esta es la política de mismo origen del navegador haciendo su trabajo: bloqueando el acceso a un recurso de un origen diferente.

CORS error
CORS error

Entendiendo el error de CORS

El error que viste en la consola es un clásico problema de CORS. Aunque ambos, cliente y servidor, corren en localhost, están en puertos diferentes—React en localhost:3000 y Express en localhost:8080.

Esto significa que se consideran orígenes diferentes según la política SOP, y el navegador bloquea la solicitud por razones de seguridad.


⚠️ Mensaje típico de error CORS

Esto es lo que probablemente te mostró el navegador:

Access to fetch at 'http://localhost:8080/' from origin 'http://localhost:3000'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is 
present on the requested resource. If an opaque response serves your needs, 
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Desglosemos esto:

  • El navegador bloquea la respuesta porque no encontró un encabezado Access-Control-Allow-Origin en la respuesta del servidor.

  • Incluso sugiere una alternativa—usar 'no-cors'—pero esto devolvería una respuesta opaca que no puedes utilizar.

  • Y lo más importante: tu cliente no hizo nada mal. CORS no es un error del lado del cliente—es una regla impuesta por el navegador según cómo responde el servidor.


✅ CORS siempre debe manejarse en el servidor

Como es la respuesta del servidor la que controla si el navegador permite el acceso, la solución adecuada es configurar tu servidor para enviar los encabezados CORS correctos.

Puedes sortear CORS en el cliente usando proxies durante el desarrollo—pero la forma segura y limpia para producción es habilitar CORS directamente en el servidor.


🔧 Habilita CORS en el servidor Express

Volvamos a app.js en tu servidor Express y actualicemos el endpoint /cors:

app.get('/cors', (req, res) => {
  res.set('Access-Control-Allow-Origin', '*');
  res.send({ msg: 'This has CORS enabled 🎈' });
});

¿Qué sucede aquí?

  • El encabezado Access-Control-Allow-Origin se establece en *, lo que significa que cualquier origen puede acceder a este recurso.

  • Esto es una forma rápida y fácil de habilitar CORS para propósitos de demostración. (Luego, tal vez quieras restringir el acceso sólo a orígenes específicos.)


🔁 Actualiza el cliente React

Ahora, regresa a tu app React y actualiza la URL del fetch para apuntar al nuevo endpoint:

const response = await fetch('http://localhost:8080/cors', { mode: 'cors' });

Guarda los cambios y reinicia el servidor de desarrollo React si es necesario.


🧪 Pruébalo

Abre tu navegador y actualiza la app. Esta vez, el navegador debería permitir la respuesta, y verás lo siguiente en tu consola:

{ data: { msg: 'This has CORS enabled 🎈' } }

¡Éxito! Acabas de realizar tu primera solicitud de origen cruzado con CORS correctamente configurado.

React CORS
CORS enabled

Confirmando la solución: ¡CORS funciona!

Cuando el encabezado CORS está correctamente configurado en el servidor, el error desaparece y tu app React recibe la respuesta como JSON. 🎉 ¡Todo funciona como se espera! No olvides que puede ser necesario reiniciar tu servidor backend después de hacer cambios para que surtan efecto.


🎯 Restringiendo CORS a orígenes específicos

En vez de usar el comodín (*), que permite que cualquier origen acceda a tus recursos, puedes restringir CORS a un dominio específico—por ejemplo, tu servidor de desarrollo React:

app.get('/cors', (req, res) => {
  res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
  res.send({ msg: 'This has CORS enabled 🎈' });
});

Esto es lo recomendado para producción para evitar que sitios no autorizados accedan a tu API.


⚠️ Cuando no puedes modificar el servidor

Aunque modificar el servidor es la forma más limpia y robusta de manejar CORS, no siempre es posible. Muchos desarrolladores se topan con esto al usar APIs de terceros—para autenticación, notificaciones, servicios de email, etc. En esos casos, no puedes cambiar la política CORS del servidor.

Si eso sucede, ¿estás atrapado… o no?


🧞‍♂️ Solución alternativa: Usar un proxy en React

Aquí tienes una solución ingeniosa, específica para el desarrollo en React: proxié tus solicitudes API a través del servidor de desarrollo.

Puedes pensar en el proxy como contestar la llamada por un compañero de clase—tu app simula que la solicitud proviene de otro origen (el del servidor), esquivando así la política SOP del navegador.

✏️ Cómo configurar un proxy

  1. Abre tu archivo package.json en la raíz del proyecto React.

  2. Agrega un campo proxy:

{
  ...
  "proxy": "http://localhost:8080"
}

  1. Reinicia tu servidor de desarrollo React (npm start), y ahora todas las solicitudes se enrutarán silenciosamente a través del backend.

Cuando haces una solicitud fetch a /cors, por ejemplo:

const response = await fetch('/cors');

Esto se proxiará internamente a http://localhost:8080/cors, haciendo que la solicitud parezca de mismo origen para el navegador.

🧪 ¿Quieres usar un servicio de terceros?

¡Sin problema! Puedes usar el proxy también así:

{
  ...
  "proxy": "https://randomservice.com"
}

Ten en cuenta:

  • Sólo solicitudes no-HTML (típicamente API) se proxían.

  • El encabezado Accept de tu solicitud no debe ser text/html.

  • Para configuraciones más complejas (ej., múltiples proxies), utiliza http-proxy-middleware para una configuración avanzada.


🧹 Resumiendo: buenas prácticas de CORS en React

Cuando se trata de CORS, esto es lo que debes recordar:

  1. Soluciona CORS siempre en el servidor—es la forma más confiable y segura.

  2. Durante el desarrollo, la configuración de proxy de React puede ayudarte a evitar problemas de CORS sin tocar el servidor.

  3. Si no controlas el servidor de la API, contacta al proveedor—o usa un proxy propio.

  4. Herramientas como extensiones Chrome tipo CORS Unblock pueden servir temporalmente, pero nunca deben usarse en producción.

  5. Siempre especifica { mode: 'cors' } en tus solicitudes fetch para dejar el comportamiento explícito.

  6. Entiende que la mayoría de los trucos en el navegador no funcionarán al desplegar en producción—planea desde el inicio.