Inicio » [SOLUCIONADO] Cross-Origin Request Blocked en Route Handlers y API Routes de Next.js
Web y Código

[SOLUCIONADO] Cross-Origin Request Blocked en Route Handlers y API Routes de Next.js

Al consumir una API creada en Next.js (utilizando el directorio App Router app/api/.../route.ts o Pages Router pages/api/...) desde una aplicación frontend externa (como una app de React Native, Flutter o un subdominio diferente), el navegador bloquea la llamada con: Access to fetch at ... from origin ... has been blocked by CORS policy: Response to preflight request doesn't pass access control check.

El Diagnóstico Rápido

Causa
Falta de cabeceras Access-Control-Allow-Origin en las respuestas del App Router de Next.js
Solución
Configurar cabeceras de respuesta en next.config.js o añadir un middleware de CORS
Causa
Navegadores bloqueando la petición previa (Preflight OPTIONS request) no manejada en route.js
Solución
Exportar una función OPTIONS en app/api/.../route.js con las cabeceras permitidas

La Solución Paso a Paso

  1. 1

    Paso 1: Manejar la petición previa OPTIONS en Next.js App Router

    Los navegadores envían una petición preliminar OPTIONS antes de cualquier POST, PUT o petición con cabeceras personalizadas. En tu archivo app/api/tu-ruta/route.js:

    JAVASCRIPT
    const corsHeaders = {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
    };
    
    export async function OPTIONS() {
      return new Response(null, {
        status: 204,
        headers: corsHeaders,
      });
    }
    
    export async function GET(request) {
      return Response.json({ mensaje: "Éxito" }, { headers: corsHeaders });
    }
    
  2. 2

    Paso 2: Configurar cabeceras CORS globales en next.config.js

    Si tienes muchas rutas API, es más limpio aplicar las cabeceras en next.config.js o next.config.mjs:

    JAVASCRIPT
    /** @type {import('next').NextConfig} */
    const nextConfig = {
      async headers() {
        return [
          {
            source: "/api/:path*",
            headers: [
              { key: "Access-Control-Allow-Credentials", value: "true" },
              { key: "Access-Control-Allow-Origin", value: "*" },
              { key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT,OPTIONS" },
              { key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version, Authorization" },
            ]
          }
        ];
      }
    };
    
    module.exports = nextConfig;
    
  3. 3

    Paso 3: Manejo de credenciales (Cookies y Authorization)

    Si tu aplicación envía cookies de sesión o tokens de autenticación con credentials: 'include', el comodín Access-Control-Allow-Origin: * será rechazado por los navegadores por seguridad. Debes especificar el dominio exacto:

    JAVASCRIPT
    'Access-Control-Allow-Origin': 'https://tu-dominio-cliente.com',
    'Access-Control-Allow-Credentials': 'true'
    

Preguntas Frecuentes

¿Por qué ocurre este error en producción pero funcionaba en localhost?

Porque en desarrollo local ambos proyectos compartían el puerto o se originaban en localhost, lo que relaja las políticas en ciertos navegadores, mientras que en producción los dominios son completamente distintos.

¿Puedo solucionar CORS usando un Middleware de Next.js?

Sí, creando un archivo middleware.js en la raíz que intercepte rutas /api/:path* e inyecte los encabezados CORS en cada NextResponse.

Consejo de Prevención

Prácticas de seguridad recomendadas:

  • Nunca uses comodines * si transmites cookies de autenticación o datos sensibles.
  • Utiliza el paquete oficial cors si sigues utilizando el Pages Router tradicional de Next.js (pages/api).
Autor • Diseñador Web & Creador de Apps

Rodolfo Castro

Diseñador web, creador de aplicaciones y fundador de SoporteCero. Especialista en desarrollo de productos digitales, interfaz de usuario y arquitectura web (Pixel Digital Dz). Cada tutorial y solución de SoporteCero es reproducido y verificado en laboratorio técnico para ofrecer guías funcionales y actualizadas.