CORS: Qué es, cómo funciona y cómo solucionarlo
Si alguna vez has desarrollado una aplicación web que consume APIs de otros dominios, probablemente te has encontrado con el temido error de CORS en la consola del navegador.
Pero, ¿qué es exactamente CORS? ¿Por qué ocurre este error y cómo podemos solucionarlo? En esta guía, responderemos todas estas preguntas de manera sencilla y práctica.
¿Qué es CORS?
CORS (Cross-Origin Resource Sharing) es un mecanismo de seguridad implementado por los navegadores para restringir las solicitudes HTTP que se realizan desde un dominio diferente al del servidor de destino.
¿Por qué existe CORS?
Los navegadores bloquean por defecto las solicitudes a recursos alojados en otros dominios para prevenir ataques maliciosos, como el Cross-Site Request Forgery (CSRF).
Imagina que tu aplicación web en https://miapp.com
quiere hacer una solicitud a https://api.ejemplo.com
. Si el servidor de api.ejemplo.com
no permite CORS, el navegador bloqueará la solicitud y mostrará un error en la consola.
Ejemplo de error CORS en la consola del navegador:
Access to fetch at 'https://api.ejemplo.com/data' from origin 'https://miapp.com' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Este error indica que el servidor no ha autorizado las solicitudes desde https://miapp.com
.
¿Cómo funciona CORS?
Cuando un navegador detecta que una solicitud es cross-origin (es decir, de un dominio diferente), verifica si el servidor permite este tipo de solicitudes.
El servidor debe responder con los encabezados CORS adecuados para que el navegador acepte la solicitud.
Ejemplo de solicitud bloqueada por CORS:
fetch('https://api.ejemplo.com/data')
.then(response => response.json())
.catch(error => console.error('Error:', error));
Si el servidor no responde con los headers correctos, el navegador bloqueará la solicitud.
Para que la solicitud funcione, el servidor debe responder con un encabezado como este:
Access-Control-Allow-Origin: https://miapp.com
Si en lugar de un dominio específico usamos *
, el servidor permitirá solicitudes de cualquier origen:
Access-Control-Allow-Origin: *
Usar *
puede ser un riesgo de seguridad si la API expone información sensible.
3. Tipos de solicitudes CORS
CORS define tres tipos de solicitudes:
Solicitudes simples (No generan preflight)
Son aquellas que cumplen con estos requisitos:
✅ Métodos permitidos: GET
, POST
, HEAD
.
✅ Headers permitidos: Content-Type: text/plain, application/x-www-form-urlencoded, multipart/form-data
.
✅ No usan Authorization
, cookies o headers personalizados.
Ejemplo (sin preflight):
fetch('https://api.ejemplo.com/data', {
method: 'GET'
})
Solicitudes preflight (El navegador envía un OPTIONS
antes de la solicitud real)
Si la solicitud no cumple las condiciones de solicitud simple, el navegador envía primero una solicitud OPTIONS para verificar si el servidor permite la operación.
Ejemplo de solicitud con preflight:
fetch('https://api.ejemplo.com/data', {
method: 'PUT',
headers: {
'Authorization': 'Bearer 123456',
'Content-Type': 'application/json'
}
})
El navegador enviará automáticamente esta solicitud OPTIONS antes de la solicitud PUT
:
OPTIONS /data HTTP/1.1
Origin: https://miapp.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Authorization, Content-Type
Si el servidor permite la solicitud, responderá con:
HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://miapp.com
Access-Control-Allow-Methods: PUT, GET, OPTIONS
Access-Control-Allow-Headers: Authorization, Content-Type
Luego de esto, el navegador procederá con la solicitud PUT
.
Solicitudes con credenciales (Cookies o Authorization)
Si una solicitud incluye credenciales (cookies
, Authorization
, session tokens
), el servidor debe permitirlo explícitamente:
Access-Control-Allow-Origin: https://miapp.com
Access-Control-Allow-Credentials: true
Ejemplo en fetch
:
fetch('https://api.ejemplo.com/data', {
method: 'GET',
credentials: 'include' // Enviar cookies o session tokens
})
⚠️ Importante: Access-Control-Allow-Origin: *
no funciona con credenciales. Se debe especificar el dominio permitido.
Ejemplos Cómo solucionar errores de CORS
Si tu navegador bloquea una solicitud por CORS, la solución depende de la configuración del servidor.
Ejemplo 1: Configurar CORS en el servidor
En Node.js con Express, puedes habilitar CORS usando el paquete cors
:
const cors = require('cors');
const app = express();
app.use(cors({ origin: 'https://miapp.com' })); // Permitir solo mi dominio
app.get('/data', (req, res) => {
res.json({ message: '¡Hola, CORS funciona!' });
});
Si deseas permitir cualquier origen, usa:
app.use(cors()); // ⚠️ Permite todas las solicitudes, cuidado con datos sensibles
Ejemplo 2: Configurar CORS en Nginx
Si usas Nginx como servidor, agrega estos headers en la configuración:
location /api/ {
add_header 'Access-Control-Allow-Origin' 'https://miapp.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
}
Ejemplo 3: Configurar CORS en el navegador (solo para pruebas)
Si solo necesitas hacer pruebas locales y evitar el bloqueo de CORS, puedes:
- Usar una extensión de Chrome como "Allow CORS: Access-Control-Allow-Origin".
- Ejecutar Chrome con el flag
--disable-web-security
(⚠️ No recomendado en producción).