CORS en React: qué es, por qué es importante y cómo habilitarlo
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.

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.

¿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.

¿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.
-
Crea la carpeta del proyecto:
mkdir cors-server && cd cors-server
-
Inicializa un nuevo proyecto Node.js:
npm init -y
Esto crea un archivo package.json
con valores por defecto.
-
Instala Express:
npm install express
-
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.
-
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í:

⚛️ 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 solicitudGET
ahttp://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.

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.

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
-
Abre tu archivo
package.json
en la raíz del proyecto React. -
Agrega un campo
proxy
:
{
...
"proxy": "http://localhost:8080"
}
-
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 sertext/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:
-
Soluciona CORS siempre en el servidor—es la forma más confiable y segura.
-
Durante el desarrollo, la configuración de proxy de React puede ayudarte a evitar problemas de CORS sin tocar el servidor.
-
Si no controlas el servidor de la API, contacta al proveedor—o usa un proxy propio.
-
Herramientas como extensiones Chrome tipo CORS Unblock pueden servir temporalmente, pero nunca deben usarse en producción.
-
Siempre especifica
{ mode: 'cors' }
en tus solicitudes fetch para dejar el comportamiento explícito. -
Entiende que la mayoría de los trucos en el navegador no funcionarán al desplegar en producción—planea desde el inicio.