Access-Control-Allow-Origin
Uso
Nota
CORS (intercambio de recursos entre orígenes) es un mecanismo del navegador que impide que las páginas web lean respuestas servidas por un origen distinto, salvo que el servidor permita el acceso de forma explícita. Los navegadores establecen la cabecera Origin automáticamente en las solicitudes entre orígenes. JavaScript no puede modificar la cabecera Origin.
Cada respuesta CORS incluye Access-Control-Allow-Origin para indicar al navegador si el código de front-end de un origen concreto puede leer la respuesta. Sin un valor coincidente, el navegador impide que la respuesta llegue a JavaScript.
Los servidores que deciden permitir el acceso tienen tres opciones: un comodín, un origen explícito o null. La mayoría de las API en producción seleccionan el origen de forma dinámica comparando la cabecera de solicitud Origin entrante con una lista de permitidos. Cuando el origen coincide, el servidor devuelve ese mismo valor. Como la respuesta cambia según la solicitud, se necesita una cabecera Vary: Origin para que las cachés almacenen copias separadas por cada origen.
Qué activa CORS
Cualquier fetch() o XMLHttpRequest hacia un origen distinto activa la aplicación de CORS. La carga de fuentes mediante @font-face, las texturas de WebGL y canvas.drawImage() sobre imágenes de otro origen también activan comprobaciones de CORS. Las solicitudes que llevan cabeceras personalizadas, métodos no simples como PUT, DELETE o PATCH, o un Content-Type application/json activan una solicitud de verificación previa OPTIONS antes de enviar la solicitud real. La navegación estándar, como hacer clic en enlaces o cargar páginas en el navegador, no activa CORS.
* (comodín)
Permite que cualquier origen lea la respuesta. El comodín solo es válido para solicitudes sin credenciales.
Access-Control-Allow-Origin: *
Nota
El comodín es incompatible con las solicitudes con credenciales. Cuando Access-Control-Allow-Credentials vale true, el servidor debe devolver un origen explícito.
Origen explícito
Un único valor de origen formado por un esquema, un nombre de host y un puerto opcional. Es el enfoque estándar para las API restringidas a llamantes conocidos.
Access-Control-Allow-Origin: https://example.com
Solo se permite un origen por respuesta. Los servidores que admiten varios orígenes inspeccionan la cabecera de solicitud Origin y responden con el valor coincidente, añadiendo Vary: Origin a la respuesta.
null
Representa un origen opaco o sensible desde el punto de vista de la privacidad. Algunos documentos en entornos aislados y las URL de archivos locales envían null como su origen.
Access-Control-Allow-Origin: null
Nota
No se recomienda responder con null. Los documentos maliciosos procedentes de iframes aislados también llevan un origen null, lo que hace que este valor sea fácil de falsificar.
Ejemplo
Un servidor refleja dinámicamente el origen solicitante e incluye una cabecera Vary para obtener un comportamiento de caché correcto.
Access-Control-Allow-Origin: https://example.com
Vary: Origin
Una CDN pública que sirve recursos estáticos a cualquier llamante utiliza el comodín.
Access-Control-Allow-Origin: *
Una respuesta entre orígenes con credenciales combina el origen explícito con la cabecera de credenciales.
Access-Control-Allow-Origin: https://dashboard.example.re
Access-Control-Allow-Credentials: true
Vary: Origin
Diagnóstico
Las solicitudes entre orígenes fallan cuando el navegador no logra hacer coincidir el origen de la respuesta con el de la página solicitante.
La consola muestra “No ‘Access-Control-Allow-Origin’ header is present on the requested resource.”. El servidor no incluyó la cabecera en absoluto. Verifique que la configuración de CORS del lado del servidor se aplique a la ruta y al método HTTP concretos. En nginx, confirme que la directiva add_header está dentro del bloque location correcto. En Apache, confirme que Header set está dentro del
El comodín * no funciona con solicitudes con credenciales. Los navegadores rechazan las respuestas que combinan Access-Control-Allow-Origin: * con Access-Control-Allow-Credentials: true. La solución es leer la cabecera Origin entrante, validar el valor contra una lista de permitidos y devolver el origen coincidente. Añada Vary: Origin a la respuesta para que las cachés almacenen copias separadas por origen.
Reflejo del origen sin validación. Devolver literalmente la cabecera de solicitud Origin sin comprobar una lista de permitidos abre la API a cualquier dominio. Los atacantes aprovechan esto para robar datos a través de una página que controlan. Compare siempre el origen entrante con una lista de valores de confianza antes de reflejarlo.
Una CDN almacena en caché una respuesta con el origen equivocado. Cuando el servidor devuelve un valor de origen dinámico pero omite Vary: Origin, la CDN guarda el primer valor de origen y sirve la misma respuesta almacenada a todos los orígenes posteriores. Añada Vary: Origin en todas las respuestas que reflejen un origen dinámico. En Cloudflare, esto se gestiona automáticamente al usar la transformación gestionada de CORS. En otras CDN, confirme que el origen forma parte de la clave de caché.
La verificación previa tiene éxito, pero la solicitud real falla. La respuesta a OPTIONS incluye las cabeceras CORS, pero la respuesta posterior a GET, POST o PUT no. Muchos frameworks de servidor tratan OPTIONS de forma independiente de los demás métodos. Asegúrese de que las cabeceras CORS se añaden a todos los tipos de respuesta, no solo a las respuestas de verificación previa. En Express, coloque el middleware de CORS antes de los manejadores de rutas para que todas las respuestas pasen por él.
La depuración con curl muestra cabeceras correctas, pero el navegador sigue bloqueando. Abra DevTools, vaya a la pestaña Network e inspeccione las cabeceras de respuesta que el navegador recibió realmente. Los proxies, los equilibradores de carga o las reglas de borde de la CDN a veces eliminan o sobrescriben las cabeceras CORS entre el servidor de origen y el navegador. Compare la salida de curl con la de DevTools para localizar la capa que elimina la cabecera.