Traducir esta página

Usando middleware

Express is a routing and middleware web framework with minimal functionality of its own: an Express application is essentially a series of middleware function calls executed during the request-response cycle.

Middleware functions are functions that have access to:

  • The request object (req)
  • The response object (res)
  • The next middleware function in the application’s request-response cycle, commonly named next

Las funciones de Middleware pueden realizar las siguientes tareas:

  • Ejecutar cualquier código.
  • Modify the request and response objects.
  • Terminar el ciclo de solicitud de respuesta.
  • Pass control to the next middleware function.

If a middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. De lo contrario, la solicitud quedará colgada.

Una aplicación Express puede utilizar los siguientes tipos de middleware:

Puede cargar middleware de nivel de aplicación y de enrutador con una ruta de montaje opcional. Multiple middleware functions can also be loaded together, which creates a middleware sub-stack at a mount point.

Middleware de nivel de aplicación

Bind application-level middleware to an instance of the app object by using the app.use() and app.METHOD() functions, where METHOD is the lowercase HTTP method of the request that the middleware function handles, such as get, post, put, or delete.

Middleware without a mount path

The following middleware function runs every time the app receives a request:

index.cjs
const express = require('express');
const app = express();
app.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});

Middleware mounted on a path

The following middleware function runs for any type of HTTP request on the /user/:id path:

app.use('/user/:id', (req, res, next) => {
console.log('Request Type:', req.method);
next();
});

Manejadores de rutas

Este ejemplo muestra una ruta y su función manejadora (middleware system). La función maneja peticiones GET a la ruta /user/:id.

app.get('/user/:id', (req, res) => {
res.send('USER');
});

Middleware sub-stacks

Multiple middleware functions can be loaded together at a mount point to form a middleware sub-stack. This example prints request info for any type of HTTP request to the /user/:id path:

app.use(
'/user/:id',
(req, res, next) => {
console.log('Request URL:', req.originalUrl);
next();
},
(req, res, next) => {
console.log('Request Type:', req.method);
next();
}
);

Multiple route handlers

Los manejadores de rutas le permiten definir múltiples rutas para una ruta. El siguiente ejemplo define dos rutas para peticiones GET a la ruta /user/:id. La segunda ruta no causará ningún problema, pero nunca se llamará porque la primera ruta termina el ciclo de solicitud de respuesta.

app.get(
'/user/:id',
(req, res, next) => {
console.log('ID:', req.params.id);
next();
},
(req, res) => {
res.send('User Info');
}
);
// handler for the /user/:id path, which prints the user ID
app.get('/user/:id', (req, res) => {
res.send(req.params.id);
});

Skipping to the next route

Call next('route') to skip the remaining middleware functions in a router middleware stack and pass control to the next route.

Note

next('ruta') solo funcionará en funciones de middleware que fueron cargadas usando las funciones app.METHOD() o router.METHOD().

In the following example, if the user ID is 0, the first handler skips to the next route, which sends a special response:

app.get(
'/user/:id',
(req, res, next) => {
// if the user ID is 0, skip to the next route
if (req.params.id === '0') next('route');
// otherwise pass the control to the next middleware function in this stack
else next();
},
(req, res) => {
// send a regular response
res.send('regular');
}
);
// handler for the /user/:id path, which sends a special response
app.get('/user/:id', (req, res) => {
res.send('special');
});

Reusable middleware arrays

Middleware functions can also be grouped into arrays for better reusability. Este ejemplo muestra una matriz con un substack de middleware que maneja peticiones GET en la ruta /user/:id

function logOriginalUrl(req, res, next) {
console.log('Request URL:', req.originalUrl);
next();
}
function logMethod(req, res, next) {
console.log('Request Type:', req.method);
next();
}
const logStuff = [logOriginalUrl, logMethod];
app.get('/user/:id', logStuff, (req, res) => {
res.send('User Info');
});

Middleware de nivel remoto

Router-level middleware works the same way as application-level middleware, except it is bound to an instance of express.Router().

const router = express.Router();

Carga el middleware a nivel de enrutador usando las funciones router.use() y router.METHOD().

El siguiente código de ejemplo replica el sistema middleware que se muestra arriba para el middleware de nivel de aplicación, mediante el uso de router-level middleware:

index.cjs
const express = require('express');
const app = express();
const router = express.Router();
// a middleware function with no mount path. This code is executed for every request to the router
router.use((req, res, next) => {
console.log('Time:', Date.now());
next();
});
// a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path
router.use(
'/user/:id',
(req, res, next) => {
console.log('Request URL:', req.originalUrl);
next();
},
(req, res, next) => {
console.log('Request Type:', req.method);
next();
}
);
// a middleware sub-stack that handles GET requests to the /user/:id path
router.get(
'/user/:id',
(req, res, next) => {
// if the user ID is 0, skip to the next route
if (req.params.id === '0') next('route');
// otherwise pass control to the next middleware function in this stack
else next();
},
(req, res) => {
// render a regular page
res.render('regular');
}
);
// handler for the /user/:id path, which renders a special page
router.get('/user/:id', (req, res) => {
console.log(req.params.id);
res.render('special');
});
// mount the router on the app
app.use('/', router);

Skipping out of a router

Use next('router') to skip the rest of the router’s middleware functions and pass control back out of the router instance.

In the following example, the router only responds when the request includes an x-auth header. Otherwise, next('router') exits the router and the app responds with a 401 status:

index.cjs
const express = require('express');
const app = express();
const router = express.Router();
// predicate the router with a check and bail out when needed
router.use((req, res, next) => {
if (!req.headers['x-auth']) return next('router');
next();
});
router.get('/user/:id', (req, res) => {
res.send('hello, user!');
});
// use the router and 401 anything falling through
app.use('/admin', router, (req, res) => {
res.sendStatus(401);
});

Middleware de manejo de errores

Define las funciones de middleware de la misma manera que otras funciones de middleware, excepto con cuatro argumentos en lugar de tres, específicamente con la firma (err, req, res, next):

app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something broke!');
});

Middleware manejado por errores siempre toma four argumentos. Debe proporcionar cuatro argumentos para identificarlo como una función de middleware que maneja errores. Incluso si no necesitas usar el objeto next , debes especificarlo para mantener la firma. De lo contrario, el objeto siguiente será interpretado como middleware regular y fallará al manejar errores.

Middleware incorporado

Express tiene las siguientes funciones de middleware incorporadas:

Middleware de terceros

Utilice middleware de terceros para añadir funcionalidad a aplicaciones Express.

Instale el módulo Node.js para la funcionalidad requerida, luego guárdelo en su aplicación a nivel de aplicación o a nivel de enrutador.

El siguiente ejemplo ilustra la instalación y carga de la función middleware cookie-parser.

Terminal window
npm install cookie-parser
index.cjs
const express = require('express');
const app = express();
const cookieParser = require('cookie-parser');
// load the cookie-parsing middleware
app.use(cookieParser());