Back

Cómo depurar errores de CORS en el navegador

Cómo depurar errores de CORS en el navegador

Ejecutas una petición fetch, abres la consola y ves algo como:

Access to fetch at ‘https://api.example.com’ from origin ‘http://localhost:3000’ has been blocked by CORS policy.

Antes de empezar a cambiar encabezados del servidor al azar, detente. La mayoría de la depuración de CORS en el navegador se reduce a leer lo que el navegador ya te está diciendo — si sabes dónde buscar.

Puntos clave

  • Los errores de CORS son aplicados por el navegador, no por el servidor. La petición a menudo llega al servidor; el bloqueo ocurre en la respuesta.
  • El mensaje de la consola del navegador es tu herramienta de diagnóstico principal — a menudo señala la regla o encabezado que falla, pero también puede reflejar problemas subyacentes de red, TLS o políticas.
  • Las peticiones preflight OPTIONS fallan silenciosamente si no las estás buscando. Siempre revisa la pestaña Network filtrada por “All” para detectarlas.
  • No todos los errores que parecen de CORS son realmente un problema de CORS. Contenido mixto, fallos de TLS, redirecciones y extensiones del navegador pueden disfrazarse como problemas de CORS.

Qué significan realmente los errores de CORS

Los errores de CORS (Cross-Origin Resource Sharing) ocurren cuando tu navegador bloquea una petición de origen cruzado porque la respuesta del servidor no incluyó los permisos correctos. La palabra clave es navegador — la petición a menudo llega al servidor. El bloqueo ocurre en el camino de vuelta.

Un origen se define por la combinación de protocolo, dominio y puerto. Así que http://localhost:3000 y http://localhost:4000 son orígenes diferentes, incluso en la misma máquina.

Cómo depurar errores de CORS usando DevTools

Abre DevTools → pestaña Network (F12 o Cmd+Option+I). Reproduce la petición que falla. Luego:

  1. Encuentra la petición fallida — busca una entrada en rojo o filtra por “Fetch/XHR”.
  2. Revisa la pestaña Console — el mensaje de error allí es específico. Te dice qué encabezado falta o no coincide.
  3. Haz clic en la petición → pestaña Headers — inspecciona tanto los encabezados de la petición (especialmente Origin) como los encabezados de respuesta (especialmente Access-Control-Allow-Origin).

El error de consola es tu herramienta de diagnóstico principal. Chrome y Firefox modernos dan mensajes precisos como:

  • “No ‘Access-Control-Allow-Origin’ header is present” → el servidor no envió ningún encabezado CORS.
  • “The value of ‘Access-Control-Allow-Origin’ must not be the wildcard ’*’ when credentials mode is ‘include’” → estás usando credentials: 'include' pero el servidor respondió con *.
  • “Method PUT is not allowed by Access-Control-Allow-Methods” → el preflight rechazó tu método HTTP.

Depuración de peticiones preflight (OPTIONS)

Cuando tu petición usa un método no simple (PUT, DELETE, PATCH), encabezados personalizados, o un tipo de contenido diferente a los pocos permitidos por la especificación, el navegador envía primero una petición preflight OPTIONS. Si esa falla, tu petición real nunca se envía.

En la pestaña Network, filtra por “All” y busca una petición OPTIONS a la misma URL, que aparece justo antes de tu petición principal. Haz clic en ella y verifica:

  • Encabezados de petición: Access-Control-Request-Method y Access-Control-Request-Headers — estos le dicen al servidor lo que la petición real necesita.
  • Encabezados de respuesta: Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Origin — el servidor debe permitir explícitamente cada uno.

Si la petición OPTIONS devuelve un código de estado 4xx o 5xx, probablemente sea un error de enrutamiento o configuración del lado del servidor, no una mala configuración de encabezados CORS. Corrige primero el error subyacente.

¿Es realmente un error de CORS?

No todos los errores que aparecen como CORS están causados por CORS. Los falsos positivos comunes incluyen:

  • Contenido mixto — obtener http:// desde una página https:// es bloqueado por la política de contenido mixto del navegador, independientemente de los encabezados CORS.
  • Errores de TLS/certificado — un handshake TLS fallido puede parecer un fallo de CORS en la consola.
  • Redirecciones a un origen diferente — si el servidor redirige tu petición a un nuevo origen, el navegador bloquea la petición. Las redirecciones de origen cruzado no están permitidas para peticiones CORS.
  • Extensiones del navegador — las extensiones de privacidad o bloqueo de anuncios pueden cancelar peticiones antes de que CORS sea siquiera evaluado.
  • Restricciones de cookies de terceros — si estás usando credentials: 'include', los navegadores modernos pueden bloquear cookies de orígenes de terceros incluso cuando tus encabezados CORS son perfectamente correctos.

Para aislar la causa real, intenta la petición en una ventana privada/incógnito con las extensiones deshabilitadas.

Peticiones con credenciales: una trampa común

Si usas fetch(url, { credentials: 'include' }), el servidor no puede responder con Access-Control-Allow-Origin: *. Debe devolver exactamente el origen que hace la petición. El servidor también necesita incluir Access-Control-Allow-Credentials: true en su respuesta. Si falta cualquiera de los dos, el navegador bloquea la respuesta.

Lista de verificación rápida para depurar CORS

VerificaciónQué buscar
Mensaje de error en consolaEncabezado o regla exacta que falló
¿Petición OPTIONS presente?Preflight activado — revisa su respuesta
¿La respuesta tiene Access-Control-Allow-Origin?Debe coincidir con tu origen o ser *
¿Usando credenciales?* no está permitido; se requiere origen exacto
¿4xx/5xx en la petición?Error del servidor — no es un problema de CORS
¿Contenido mixto?HTTP desde página HTTPS — siempre bloqueado

Conclusión

El mensaje de error del navegador, la pestaña Network y el panel Headers te dan todo lo que necesitas para diagnosticar la mayoría de los problemas de CORS en menos de cinco minutos. Lee el error exacto, encuentra la petición OPTIONS si existe una, compara lo que se envió con lo que se esperaba, y trabaja desde ahí. Resiste la tentación de agregar ciegamente Access-Control-Allow-Origin: * a tu servidor — entiende primero lo que el navegador está pidiendo, y responde con precisión.

Preguntas frecuentes

No. CORS es aplicado por el navegador basándose en los encabezados que envía el servidor. El frontend no puede anular esto. Si no controlas el servidor, puedes enrutar las peticiones a través de un proxy backend que agregue los encabezados correctos, pero el código del lado del navegador por sí solo no puede eludir la restricción.

Postman no es un navegador y no aplica la política del mismo origen. Envía peticiones directamente sin verificar los encabezados CORS en la respuesta. Los navegadores aplican CORS para proteger a los usuarios, por lo que una petición que tiene éxito en Postman aún puede ser bloqueada por el navegador si el servidor omite los encabezados de respuesta requeridos.

Un preflight se desencadena cuando la petición usa un método diferente a GET, HEAD o POST, incluye encabezados personalizados, o establece un Content-Type diferente a application/x-www-form-urlencoded, multipart/form-data o text/plain. El navegador envía primero una petición OPTIONS para confirmar que el servidor permite la petición real.

Si tu petición incluye credenciales como cookies o encabezados de autorización, el servidor no puede usar el valor comodín. Debe responder con el origen exacto que hizo la petición y también incluir el encabezado Access-Control-Allow-Credentials establecido en true. El comodín solo es válido para peticiones sin credenciales.

Gain control over your UX

See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay