¿Odias los anuncios? Ir Sin publicidad Hoy

CORS Explicado Cómo depurar errores de origen cruzado sin perder el control

Publicado el
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: Acceso a fetch en 'https://api.example.com' desde
ANUNCIO · ¿ELIMINAR?

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 ser true expresamente.
  • 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 absolutoa la respuestaAñ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 credencialesRefleja condicionalmente el encabezado de origen de la solicitud; elimina el asterisco cuando se usan credencialesEl método PUT no está permitido por Access-Control-Allow-Methods
El método HTTP no está listado en el encabezado de métodos permitidosAgrega el método faltante aEl encabezado de solicitud 'Authorization' no está permitido por Access-Control-Allow-Headers Access-Control-Allow-Methods
El encabezado personalizado no está en la lista permitidaAgrega el encabezado aLa 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 encabezadosManeja explícitamente la solicitud OPTIONS; devuelve 200/204 con encabezados correctosLas credenciales no están soportadas si el encabezado CORS 'Access-Control-Allow-Origin' es '*'
Uso de asterisco con modo de credencialesReemplazapor 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

  1. — te dice exactamente qué encabezado o valor está mal. Verifica la pestaña de red
  2. — mira las cabeceras de respuesta reales, no lo que crees que configuraste. Verifica si hay una solicitud OPTIONS
  3. — si falla o está ausente, tu servidor no está manejando el preflight. Asegúrate de que el origen coincida exactamente
  4. — los guiones finales, HTTP vs HTTPS y los números de puerto importan. Elimina el asterisco si usas credenciales
  5. — son mutuamente excluyentes. Verifica que los encabezados no sean eliminados por un proxy
  6. — 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

¿Quieres eliminar publicidad? Adiós publicidad hoy

Instalar extensiones

Agregue herramientas IO a su navegador favorito para obtener acceso instantáneo y búsquedas más rápidas

añadir Extensión de Chrome añadir Extensión de borde añadir Extensión de Firefox añadir Extensión de Opera

¡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!

ANUNCIO · ¿ELIMINAR?
ANUNCIO · ¿ELIMINAR?
ANUNCIO · ¿ELIMINAR?

Noticias Aspectos técnicos clave

Involucrarse

Ayúdanos a seguir brindando valiosas herramientas gratuitas

Invítame a un café
ANUNCIO · ¿ELIMINAR?