¿Qué es CORS (Cross-Origin Resource Sharing)?

Actualizado: septiembre de 2026

CORS es un mecanismo del navegador que permite al servidor declarar qué otros origins pueden llamarlo, relajando a propósito la política de same-origin. Dos reencuadres disuelven la mayor parte de la confusión: quien lo aplica es el navegador (no el servidor — por eso curl funciona), y quien lo corrige es el servidor (no tu frontend — por eso ninguna cantidad de JavaScript ayuda). Todo lo demás son headers.

Puntos clave

PreguntaRespuesta
El fundamentoPolítica de same-origin: los scripts no leen respuestas de otros origins por defecto
Un originesquema + host + puerto — los tres deben coincidir
CORSHeaders del servidor haciendo opt-in de origins específicos; el navegador aplica
PreflightUn OPTIONS “¿puedo?” antes de solicitudes no simples
La verdad eternaLos errores de CORS se corrigen en el servidor, punto

El protocolo entero, en el cable

# Preflight: el navegador pregunta antes de un PUT con header de autenticación
OPTIONS /classes/Product HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: x-parse-session-token

# El permiso por escrito del servidor
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://app.example.com   ← este origin puede leer
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: x-parse-session-token
Access-Control-Max-Age: 86400        ← cachea esta respuesta; sáltate el preflight de mañana

# Entonces, y solo entonces, vuela la solicitud real.

Cómo se ve desde el código de la aplicación — y la verdad de plataforma que las pestañas enseñan: CORS es un asunto del navegador, con el que las apps nativas nunca se topan:

// Browser JavaScript — Back4app JS SDK
// A cross-origin call that just works: the platform answers the
// preflight and sends the CORS headers, so the browser lets it through
Parse.initialize('APP_ID', 'JS_KEY');
Parse.serverURL = 'https://parseapi.back4app.com'; // different origin than your site

const products = await new Parse.Query('Product').find();
// No proxy hacks, no "disable CORS" — the server side is configured correctly.

El flujo, decidido

Cómo un navegador decide una solicitud cross-originLas solicitudes same-origin proceden directo; las solicitudes cross-origin simples se envían y su respuesta se verifica en busca de un header allow-origin; las solicitudes no simples disparan primero un preflight OPTIONS, y cualquier header ausente o que no coincida hace que el navegador bloquee la respuesta para la página.

no

no

el header coincide con el origin

ausente / no coincide

Un script hace una solicitud

¿Mismo origin?

Procede, sin CORS de por medio

¿Solicitud simple?
(GET/HEAD/POST, headers de la safelist)

Envía; verifica en la respuesta el
Access-Control-Allow-Origin

Preflight OPTIONS primero

Respuesta legible

Bloqueada por el navegador
(el error de la consola)

Las solicitudes same-origin proceden directo; las solicitudes cross-origin simples se envían y su respuesta se verifica en busca de un header allow-origin; las solicitudes no simples disparan primero un preflight OPTIONS, y cualquier header ausente o que no coincida hace que el navegador bloquee la respuesta para la página.

Dos detalles cargan con la mayoría de las sesiones de depuración: una solicitud simple (GET/HEAD/POST con headers de la safelist y content types comunes) se salta el preflight — por eso agregar un header Authorization de repente “rompe” un endpoint que funcionaba; y las solicitudes con credenciales lo aprietan todo — las cookies solo fluyen con Access-Control-Allow-Credentials: true más un origin exacto, nunca el wildcard, según la especificación.

Cómo corregir errores de CORS (error → causa → corrección)

La consola diceLo que realmente pasóCorrección (siempre server-side)
No ‘Access-Control-Allow-Origin’ headerEl servidor nunca hizo opt-in de tu originAgrega tu origin a la lista permitida
Origin not allowed by Access-Control-Allow-OriginLa allow-list existe; tú no estás en ellaAgrega el esquema+host+puerto exactos
Response to preflight… doesn’t passOPTIONS sin manejar o headers incompletosResponde el OPTIONS con métodos/headers
Wildcard ’*’ cannot be used with credentialsCookies + * — combinación prohibidaLista los origins explícitamente
Request header not allowedHeader personalizado fuera de la allow-listAgrégalo a Access-Control-Allow-Headers

Y el anti-arreglo que merece nombre: deshabilitar con flags del navegador y los proxies permisivos de desarrollo vuelven el error invisible solo en tu máquina — el despliegue sigue roto para los usuarios. La corrección real es una configuración de servidor medida en minutos.

Casos de uso comunes

  • SPA + API en origins distintos — app.example.com llamando a api.example.com: el caso cotidiano para el que existe CORS.
  • Desarrollo local — localhost:3000 contra un backend real; permite el origin de desarrollo, no apagues el escudo.
  • APIs públicas — origin wildcard, sin credenciales: correcto y seguro para datos genuinamente públicos.
  • Plataformas multi-frontend — varias apps, un backend, una lista explícita de origins por entorno.
  • Backends BaaS — la plataforma responde los preflights y envía los headers; tu trabajo se reduce a declarar los origins permitidos.

Wildcard vs. origins explícitos: matriz de decisión

ConfiguraciónCorrecta cuando…Nunca cuando…
Wildcard *API pública, sin credencialesExisten cookies o sesiones de usuario
Lista explícita de originsAPIs privadas, apps con credenciales— (esta es la respuesta por defecto)
Reflejar el origin de la solicitudCasi nuncaCombinada con credenciales — el agujero clásico
Listas por entornoHigiene de dev/staging/prodProducción heredando las entradas localhost de dev

Un reencuadre de seguridad cierra la matriz: CORS no es control de acceso — las apps nativas y los servidores lo ignoran por completo, así que protege a los usuarios del navegador de sitios maliciosos, no a tu API de sus llamadores. La autenticación y los permisos en la capa de datos hacen ese trabajo; CORS solo decide qué scripts de qué sitios pueden leer las respuestas.

Limitaciones y trade-offs

  • Solo gobierna navegadores. Cualquier cosa que no sea un navegador pasa de largo — nunca confundas una lista de origins con autorización.
  • Los preflights cuestan un round trip en solicitudes no simples; el cache vía Access-Control-Max-Age es la corrección barata y olvidada.
  • La mala configuración falla cerrada y ruidosa — bueno para la seguridad, brutal para depurar sin la tabla error→corrección de arriba.
  • Las listas de origins son estado de entorno. Los origins de staging se cuelan en las configuraciones de producción; audita la lista como cualquier credencial.
  • CORS ≠ CSRF ≠ CSP. Siglas vecinas, defensas separadas — las cookies aún necesitan protección SameSite/token, las páginas aún necesitan una content policy, y CORS se encarga solo de la lectura cross-origin.

CORS en Back4app

Back4app es una plataforma open-source de Backend as a Service (BaaS) que combina base de datos gestionada, APIs REST y GraphQL generadas automáticamente, autenticación, almacenamiento de archivos y funciones serverless con Cloud Code. La tarea de CORS llega resuelta: las APIs de la plataforma responden los preflights y envían los headers correctos, así que las apps de navegador llaman al backend desde los origins permitidos sin hacks de proxy — la pestaña de JavaScript de arriba es la experiencia entera — mientras las pestañas de Flutter, Swift y Kotlin demuestran la verdad más silenciosa: los clientes nativos nunca se topan con la ceremonia. La seguridad real se queda donde pertenece: sesiones, ACLs y permisos a nivel de clase aplicados server-side en cada solicitud, venga del origin que venga.

Preguntas frecuentes

¿Qué es CORS en términos simples?

El sistema de permisos del navegador para llamadas de API entre sitios. Por defecto, los scripts de un origin no pueden leer respuestas de otro — la política de same-origin. CORS es cómo un servidor hace el opt-in: headers de respuesta que declaran qué origins, métodos y headers acepta. El navegador aplica; el servidor declara; tu código de frontend es solo el mensajero.

¿Qué es un origin, exactamente?

La tripleta de esquema, host y puerto. https://app.example.com y https://api.example.com son origins distintos (difiere el host); también las versiones http y https de un mismo sitio (difiere el esquema), y :3000 vs :8080 en desarrollo (difiere el puerto). Toda decisión de CORS compara esas tres partes — nada más de la URL importa.

¿Cómo resolver un error de CORS?

El navegador llamó a un origin distinto y la respuesta no traía un header Access-Control-Allow-Origin que coincidiera con el tuyo — así que el navegador impidió que tu script la leyera. La solicitud muchas veces llegó bien al servidor; el bloqueo es client-side, en la lectura. Por eso la corrección es siempre configuración del servidor — agregar tu origin a la lista permitida — y nunca código de frontend.

¿Qué es una solicitud de preflight?

La verificación previa de permiso del navegador para solicitudes no simples: antes de enviar un PUT, un DELETE o cualquier cosa con headers personalizados, como un token de autorización, envía una solicitud OPTIONS preguntando "¿puedo?". Los headers del servidor responden qué métodos, headers y origins están permitidos; solo entonces vuela la solicitud real. Los preflights son cacheables vía Access-Control-Max-Age.

¿Por qué mi solicitud funciona en curl pero falla en el navegador?

Porque CORS es aplicación por parte del navegador, no rechazo por parte del servidor. Herramientas como curl y las apps móviles nativas no tienen política de same-origin, así que leen la respuesta sin problema. El navegador aplica la política en nombre de su usuario — la diferencia que estás viendo es el punto de aplicación, y es también la prueba de que CORS no es control de acceso.

¿Access-Control-Allow-Origin: * es seguro?

Para APIs genuinamente públicas y sin credenciales, sí. El wildcard está prohibido en modo con credenciales — los navegadores rechazan cookies contra él por diseño — y reflejar origins arbitrarios mientras se permiten credenciales es la mala configuración clásica que convierte a CORS de escudo en agujero. Las APIs privadas listan origins explícitamente.

¿Puedo simplemente deshabilitar CORS para arreglar el error?

Solo en el sentido en que quitar la alarma de humo arregla el incendio. Las flags del navegador y los proxies permisivos enmascaran el síntoma en tu máquina mientras le entregan la falla a cada usuario. La corrección correcta toma minutos: configura el servidor (o el dashboard de la plataforma) para permitir los origins que deben llamarlo.

¿Cuál es la diferencia entre CORS, CSRF y CSP?

Tres trabajos distintos. CORS gobierna qué origins pueden leer respuestas de un servidor. CSRF es un ataque — montarse en las cookies de un usuario para forjar solicitudes — contrarrestado con tokens y cookies SameSite, no con CORS. CSP es la política de la propia página restringiendo qué puede cargar y ejecutar, la herramienta anti-XSS. Siglas vecinas, mecanismos ortogonales.

Términos relacionados

Compara con

Lecturas recomendadas

¿Listo para construir tu backend?

Empieza tu proyecto en Back4app en minutos — base de datos, autenticación, APIs y Cloud Code incluidos. Sin tarjeta de crédito.

Escrito y revisado por Back4app Engineering, Back4app Engineering · Publicado el 2026-09-03