CORS Explicado Cómo depurar errores de origen cruzado sin perder el control
Has realizado una solicitud de fetch. La pestaña de red muestra que se ha emitido, pero en el consola hay una pared de rojos: El acceso a fetch en 'https://api.example.com' desde el origen 'https://yourapp.com' ha sido bloqueado por la política CORS.
Antes de entrar en explicaciones — aquí está el camino más rápido para diagnosticar. Abre DevTools → pestaña de red → encuentra la solicitud fallida → mira la Cabeceras de respuesta. Si no las ves, Access-Control-Allow-Origintu servidor no está enviando cabeceras CORS. Esa es la solución. El resto de este artículo explica exactamente qué enviar y por qué.
¿Qué es realmente CORS?
CORS — Compartición de Recursos entre Origenes — es impuesta por el navegador, no por tu servidor. Tu API no bloquea inherentemente las solicitudes de origen cruzado. El navegador lo hace, en nombre de los usuarios, para evitar que scripts en evil.com le lean silenciosamente tus datos bancarios.
El navegador verifica: «¿La respuesta de esa API me dice que está bien para que este origen la lea?». Si no, bloquea la respuesta —aunque el servidor ya procesó la solicitud y devolvió un 200. El servidor nunca sabe por qué el cliente la descartó.
Esto importa al momento de depurar: el error siempre está en el lado del cliente. El servidor debe decirle al navegador: «sí, este origen está permitido». Esa es la función de las cabeceras de respuesta CORS.
Solicitudes simples vs solicitudes preflight
No todas las solicitudes de origen cruzado se comportan de la misma manera. El navegador distingue entre dos tipos.
Solicitudes simples son solicitudes GET o POST con cuerpos en texto plano o codificados como formulario y un conjunto pequeño de cabeceras permitidas. El navegador las envía directamente y verifica la respuesta para Access-Control-Allow-Origin.
Solicitudes preflight ocurren primero cuando tu solicitud no cumple con esas condiciones —por ejemplo, cuando envías un PUT o DELETE, incluyes un encabezado personalizado como Authorization o Content-Type: application/json, o envías credenciales. El navegador lanza automáticamente una solicitud OPTIONS al mismo URL antes de tu solicitud real. Si el servidor no responde a esa OPTIONS llamada con las cabeceras CORS correctas, tu solicitud real nunca sale.
Si estás viendo OPTIONS solicitudes en tu pestaña de red que devuelven 404 o 405, eso es por qué tus solicitudes fallan. Tu servidor debe manejar OPTIONS para cada ruta que reciba tráfico de origen cruzado.
Los encabezados que importan
Obtener el fix de cabeceras CORS correcto significa entender qué controla cada encabezado de respuesta:
Access-Control-Allow-Origin— qué orígenes pueden leer la respuesta. O bien un origen específico (https://yourapp.com) o*para cualquier origen.Access-Control-Allow-Methods— qué métodos HTTP están permitidos (por ejemplo,GET, POST, PUT, DELETE, OPTIONS).Access-Control-Allow-Headers— qué encabezados de solicitud puede enviar el navegador (por ejemplo,Authorization, Content-Type).Access-Control-Allow-Credentials— si se pueden enviar cookies y encabezados de autenticación con la solicitud. Debe sertrueexpresamente.Access-Control-Max-Age— durante cuántos segundos en segundos el navegador debe cachear la respuesta de preflight.
El error del asterisco
Usar Access-Control-Allow-Origin: * es la forma más rápida de abrir tu API — pero falla en el momento en que se requiere credencial. Cuando Access-Control-Allow-Credentials: true se requiere, el asterisco es rechazado por el navegador. Debes especificar el origen exacto:
# This will fail with credentials:
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
# This works:
Access-Control-Allow-Origin: https://yourapp.com
Access-Control-Allow-Credentials: true
Si tienes múltiples orígenes permitidos, lee el encabezado de la solicitud y responde condicionalmente —no los concatenes. Origin Errores CORS comunes y lo que significan
El mensaje de error del navegador normalmente te dice exactamente qué falta. Aquí tienes una referencia rápida:
Mensaje de error
| ¿Qué significa? | ¿Cómo solucionarlo? | No hay encabezado 'Access-Control-Allow-Origin' |
|---|---|---|
| El servidor no envió encabezados CORS en absoluto | a la respuesta | Añadir Access-Control-Allow-Origin El valor del encabezado 'Access-Control-Allow-Origin' … no coincide con el origen proporcionado |
| Desacuerdo de orígenes — el servidor devolvió un origen incorrecto o con asterisco cuando se usan credenciales | Refleja condicionalmente el encabezado de origen de la solicitud; elimina el asterisco cuando se usan credenciales | El método PUT no está permitido por Access-Control-Allow-Methods |
| El método HTTP no está listado en el encabezado de métodos permitidos | Agrega el método faltante a | El encabezado de solicitud 'Authorization' no está permitido por Access-Control-Allow-Headers Access-Control-Allow-Methods |
| El encabezado personalizado no está en la lista permitida | Agrega el encabezado a | La respuesta a la solicitud preflight no pasa la verificación de acceso controlado Access-Control-Allow-Headers |
| La solicitud OPTIONS devolvió un estado incorrecto o faltan encabezados | Maneja explícitamente la solicitud OPTIONS; devuelve 200/204 con encabezados correctos | Las credenciales no están soportadas si el encabezado CORS 'Access-Control-Allow-Origin' es '*' |
| Uso de asterisco con modo de credenciales | Reemplaza | por un origen explícito; agrega * Cómo configurar CORS en Express, FastAPI y Nginx Access-Control-Allow-Credentials: true |
Express (Node.js)
FastAPI (Python)
const cors = require('cors');
app.use(cors({
origin: 'https://yourapp.com',
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
maxAge: 86400
}));
// Handle preflight for all routes
app.options('*', cors());
Nginx
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://yourapp.com"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
Nota el patrón de Nginx: necesitas
location /api/ {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' 'https://yourapp.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Max-Age' 86400;
add_header 'Content-Length' 0;
return 204;
}
add_header 'Access-Control-Allow-Origin' 'https://yourapp.com';
add_header 'Access-Control-Allow-Credentials' 'true';
proxy_pass http://backend;
}
en ambos el add_header bloque y el bloque principal. Los encabezados establecidos dentro del OPTIONS bloque no se transfieren al bloque externo. if Tu checklist de depuración
Cuando encuentres un error de CORS, sigue este orden:
Lee el mensaje de error completo
- — te dice exactamente qué encabezado o valor está mal. Verifica la pestaña de red
- — mira las cabeceras de respuesta reales, no lo que crees que configuraste. Verifica si hay una solicitud OPTIONS
- — si falla o está ausente, tu servidor no está manejando el preflight. Asegúrate de que el origen coincida exactamente
- — los guiones finales, HTTP vs HTTPS y los números de puerto importan. Elimina el asterisco si usas credenciales
- — son mutuamente excluyentes. Verifica que los encabezados no sean eliminados por un proxy
- — Nginx y CDNs a veces eliminan o sobrescriben encabezados CORS. Un error fácil de pasar por alto: si tu API está detrás de un proxy inverso o CDN, esa capa puede agregar su propio
encabezado que conflicte con lo que devuelve tu servidor. Cuando aparecen dos de esos encabezados en una sola respuesta, el navegador rechaza todo. Siempre verifica las cabeceras de respuesta en nivel de red —no solo lo que emite tu código de aplicación. Access-Control-Allow-Origin Otro caso extremo: algunos frameworks solo adjuntan encabezados CORS a rutas que coincidan con un manejador registrado. Si estás recibiendo un 404 o una ruta no registrada, el middleware de CORS puede nunca ejecutarse, y verás el error «sin encabezado presente» aunque tu configuración parezca correcta. Prueba con un punto de entrada válido primero.
Si necesitas generar rápidamente los encabezados CORS exactos que debe devolver tu servidor, el
IO Tools CORS Headers Builder te permite configurar origen, métodos y credenciales y te entrega el bloque de encabezados correcto listo para pegar en tu configuración del servidor. Una nota sobre seguridad
CORS no es un mecanismo de seguridad de API. Establecer
no hace que tu API sea pública en ningún sentido de superficie de ataque — curl, Postman y llamadas entre servidores nunca están sujetas a restricciones de CORS. Solo las llamadas desde el navegador con JavaScript sí. Si tu API requiere autenticación, implementa la seguridad en el nivel de la API con tokens o sesiones. Los encabezados CORS solo informan al navegador sobre qué orígenes están permitidos para leer respuestas desde JavaScript. Son independientes del control de acceso real. Access-Control-Allow-Origin: * Con este contexto, puedes tomar decisiones sensatas sobre tu configuración de CORS en lugar de cerrar todo por miedo a una inseguridad o abrir todo sin entender el costo.
CORS Explicado: Cómo depurar errores de origen cruzado sin perder el control 2
También te puede interesar
Instalar extensiones
Agregue herramientas IO a su navegador favorito para obtener acceso instantáneo y búsquedas más rápidas
恵 ¡El marcador ha llegado!
Marcador es una forma divertida de llevar un registro de tus juegos, todos los datos se almacenan en tu navegador. ¡Próximamente habrá más funciones!
Herramientas clave
Ver todo Los recién llegados
Ver todoActualizar: Nuestro última herramienta was added on May 10, 2026
