Volver a la lista

Servicio de archivos estáticos y gestión de errores.

Aprenda a servir archivos HTML, CSS e imágenes con Express y a gestionar los errores 404 y 500 de forma eficiente.

Intermedio
|
10min
|
Verificado (2026-07)
archivos estáticosExpressmanejo de errorespágina 404middleware
Progreso0/55 (0%)

Servicio de archivos estáticos y gestión de errores

Al finalizar este tema

Podrás servir archivos estáticos como HTML, CSS e imágenes con Express, y gestionar de forma estructurada los errores 404 (página no encontrada) y 500 (error del servidor).


¿Qué son los archivos estáticos?

Existen dos tipos de archivos que gestiona un servidor web:

  • Archivos dinámicos: respuestas generadas por el servidor al ejecutar código en cada solicitud (API, resultados de consultas a bases de datos)
  • Archivos estáticos: archivos que el servidor simplemente transmite sin modificaciones (HTML, CSS, JavaScript, imágenes, fuentes)

La lista de entradas de un blog es dinámica, pero la imagen del logotipo y las hojas de estilo del blog son estáticas. Dado que los archivos estáticos no necesitan crearse desde cero en cada solicitud, se gestionan de forma eficiente mediante un middleware especializado.


express.static: middleware para archivos estáticos

Express incluye el middleware express.static().

text
project/
├── app.js
├── public/
│   ├── index.html
│   ├── css/
│   │   └── style.css
│   ├── js/
│   │   └── main.js
│   └── images/
│       └── logo.png
javascript
const express = require('express');
const path = require('path');
const app = express();

// Configurar la carpeta public como raíz de archivos estáticos
app.use(express.static(path.join(__dirname, 'public')));

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

Ahora, al acceder a http://localhost:3000/css/style.css desde el navegador, se mostrará el archivo public/css/style.css. Ya no es necesario agregar /public a la URL, ya que express.static asigna la carpeta public como directorio raíz.

Agregar un prefijo a la URL

javascript
// Acceder a /assets/css/style.css
app.use('/assets', express.static(path.join(__dirname, 'public')));

El primer argumento es el prefijo de la URL. De este modo, la ruta real del archivo será public/css/style.css, pero la URL será /assets/css/style.css. Esto es útil para separar las rutas con fines de CDN o control de versiones.

Especificación de varias carpetas

javascript
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'uploads')));

Puede registrar ambas carpetas como fuentes de archivos estáticos. Si no se encuentran los archivos en la primera carpeta, se buscará en la segunda. El orden establece la prioridad.


path.join y __dirname: creación de rutas de forma segura

javascript
// Mal: ruta relativa — varía según la ubicación de ejecución
app.use(express.static('public'));

// Bien: ruta absoluta — funciona igual sin importar dónde se ejecute
app.use(express.static(path.join(__dirname, 'public')));

__dirname es la ruta absoluta del directorio que contiene el archivo actual. path.join() gestiona automáticamente los separadores de ruta apropiados para el sistema operativo (/ o \). En Windows, escribir / directamente puede causar problemas; por lo tanto, siempre se debe usar path.join.


Manejo de errores 404: página no encontrada

En Express, si una solicitud no coincide con ninguna ruta, simplemente se ignora. El cliente esperará indefinidamente una respuesta. Para evitar esto, se debe colocar un controlador de errores 404 después de todas las rutas.

javascript
// Definir ruta
app.get('/', (req, res) => {
  res.send('Home');
});

app.get('/about', (req, res) => {
  res.send('About');
});

// Manejador 404 — después de todas las rutas, antes del manejador de errores
app.use((req, res) => {
  res.status(404).json({
    error: 'Not Found',
    message: `${req.method} ${req.url} does not exist`,
    status: 404
  });
});

La ubicación es importante. Dado que app.use() se ejecutan en secuencia, si se coloca el controlador de errores 404 al principio, todas las solicitudes devolverán un error 404. Debe colocarse siempre después de todas las definiciones de rutas.

Página HTML de 404

Si no es un servidor de API, sino un sitio web, es más lógico mostrar una página HTML en lugar de JSON.

javascript
app.use((req, res) => {
  res.status(404).sendFile(path.join(__dirname, 'public', '404.html'));
});

Manejo de errores 500 — Error interno del servidor

El middleware de manejo de errores tiene cuatro parámetros. Express distingue entre middleware estándar y manejadores de errores mediante esta firma.

javascript
// Manejador de errores — después del manejador 404
app.use((err, req, res, next) => {
  console.error(`[ERROR] ${err.stack}`);

  res.status(err.status || 500).json({
    error: 'Internal Server Error',
    message: process.env.NODE_ENV === 'production'
      ? 'Something went wrong'
      : err.message,
    status: err.status || 500
  });
});

Dos puntos a tener en cuenta:

  1. En el entorno de producción, los mensajes de error se ocultan. Esto se debe a que err.message puede contener información confidencial, como consultas SQL o rutas de archivos. Los mensajes detallados solo se muestran en el entorno de desarrollo.

  2. Cómo generar errores: Al llamar a next(err) dentro de una ruta, se redirige al controlador de errores.

javascript
app.get('/users/:id', async (req, res, next) => {
  try {
    const user = await findUser(req.params.id);
    if (!user) {
      const err = new Error('User not found');
      err.status = 404;
      return next(err);
    }
    res.json(user);
  } catch (err) {
    next(err); // Errores inesperados como errores de DB
  }
});

Estructura general — orden correcto

javascript
const express = require('express');
const path = require('path');
const app = express();

// 1. Middleware básico
app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));

// 2. Rutas
app.get('/api/users', (req, res) => { /* ... */ });
app.post('/api/users', (req, res) => { /* ... */ });

// 3. Manejador de 404 (después de las rutas)
app.use((req, res) => {
  res.status(404).json({ error: 'Not Found' });
});

// 4. Manejador de errores (siempre al final)
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Internal Server Error' });
});

app.listen(3000);

Este orden corresponde a la estructura estándar de un proyecto Express: middleware base → rutas → 404 → error. Si se incumple este orden, se producirán comportamientos inesperados.


Errores comunes en la práctica

ErrorSíntomaSolución
El controlador 404 se define antes que las rutasTodas las solicitudes devuelven 404Mover el controlador 404 al final
El controlador de errores tiene 3 parámetrosLos errores no se capturanSe requieren (err, req, res, next) parámetros
La ruta express.static es relativaNo se encuentran los archivos si se ejecuta desde otra carpetaUsar path.join(__dirname, ...)
No se llama a next(err) en el controlador de erroresEl controlador de errores no se ejecutaLlamar a try/catch + next(err)
Se expone err.stack en producciónVulnerabilidad de seguridadUsar la rama condicional de NODE_ENV

Resumen clave

El manejo de archivos estáticos y errores cubre tanto los casos "cuando el servidor funciona correctamente" como "cuando no funciona". express.static sirve los archivos de manera eficiente, mientras que los controladores 404/500 garantizan respuestas significativas para el usuario incluso en situaciones excepcionales. Recordar el orden del middleware de Express (análisis → archivos estáticos → rutas → 404 → error) evita confusiones sobre dónde colocar cada elemento.


💬 Preguntas y comentarios

0 comentarios

Puedes publicar sin iniciar sesión. Los comentarios de invitados no pueden editarse ni eliminarse después.

0/2000

Cargando...