Express и Node.js обучение от StrongLoop

Этот документ может быть устаревшей по отношению к документации на английском языке . Для получения последних обновлений , пожалуйста, обратитесь к документации на английском языке.

This document might be outdated relative to the documentation in English. For the latest updates, please refer the documentation in English.

Using middleware

An Express application is essentially a series of middleware calls.

Middleware is a function with access to the request object (req), the response object (res), and the next middleware in line in the request-response cycle of an Express application, commonly denoted by a variable named next. Middleware can:

If the current middleware does not end the request-response cycle, it must call next() to pass control to the next middleware, otherwise the request will be left hanging.

With an optional mount path, middleware can be loaded at the application level or at the router level. Also, a series of middleware functions can be loaded together, creating a sub-stack of the middleware system at a mount point.

An Express application can use the following kinds of middleware:

Application level middleware

Application level middleware are bound to an instance of express, using app.use() and app.VERB().

var app = express();

// a middleware with no mount path; gets executed for every request to the app
app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

// a middleware mounted on /user/:id; will be executed for any type of HTTP request to /user/:id
app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

// a route and its handler function (middleware system) which handles GET requests to /user/:id
app.get('/user/:id', function (req, res, next) {
  res.send('USER');
});

Here is an example of loading a series of middleware at a mount point with a mount path.

// a middleware sub-stack which prints request info for any type of HTTP request to /user/:id
app.use('/user/:id', function(req, res, next) {
  console.log('Request URL:', req.originalUrl);
  next();
}, function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

Route handlers, being a middleware system, makes it possible to define multiple routes for a path. In the example below, two routes are defined for GET requests to /user/:id. The second router will not cause any problems, however it will never get called, because the first route ends the request-response cycle.

// a middleware sub-stack which handles GET requests to /user/:id
app.get('/user/:id', function (req, res, next) {
  console.log('ID:', req.params.id);
  next();
}, function (req, res, next) {
  res.send('User Info');
});

// handler for /user/:id which prints the user id
app.get('/user/:id', function (req, res, next) {
  res.end(req.params.id);
});

If you need to skip the rest of the middleware from a router middleware stack, call next('route') to pass on the control to the next route. Note: next('route') will work only in middleware loaded using app.VERB() or router.VERB().

// a middleware sub-stack which handles GET requests to /user/:id
app.get('/user/:id', function (req, res, next) {
  // if user id is 0, skip to the next route
  if (req.params.id == 0) next('route');
  // else pass the control to the next middleware in this stack
  else next(); // 
}, function (req, res, next) {
  // render a regular page
  res.render('regular');
});

// handler for /user/:id which renders a special page
app.get('/user/:id', function (req, res, next) {
  res.render('special');
});

Router level middleware

Router level middleware work just like application level middleware except they are bound to an instance of express.Router().

var router = express.Router();

Router level middleware are loaded using router.use() and router.VERB().

The middleware system created at the application level in the example above, can be replicated at the router level using the following code.

var app = express();
var router = express.Router();

// a middleware with no mount path, gets executed for every request to the router
router.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

// a middleware sub-stack shows request info for any type of HTTP request to /user/:id
router.use('/user/:id', function(req, res, next) {
  console.log('Request URL:', req.originalUrl);
  next();
}, function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

// a middleware sub-stack which handles GET requests to /user/:id
router.get('/user/:id', function (req, res, next) {
  // if user id is 0, skip to the next router
  if (req.params.id == 0) next('route');
  // else pass the control to the next middleware in this stack
  else next(); // 
}, function (req, res, next) {
  // render a regular page
  res.render('regular');
});

// handler for /user/:id which renders a special page
router.get('/user/:id', function (req, res, next) {
  console.log(req.params.id);
  res.render('special');
});

// mount the router on the app
app.use('/', router);

Built-in middleware

As of 4.x, Express no longer depends on Connect. Except for express.static, all of Express’ previously included middleware are now in separate repos. Please view the list of middleware.

express.static(root, [options])

express.static is based on serve-static, and is responsible for serving the static assets of an Express application.

The root argument refers to the root directory from which the static assets are to be served.

The optional options object can have the following properties.

Here is an example of using the express.static middleware with an elaborate options object.

var options = {
  dotfiles: 'ignore',
  etag: false,
  extensions: ['htm', 'html'],
  index: false,
  maxAge: '1d',
  redirect: false,
  setHeaders: function (res, path, stat) {
    res.set('x-timestamp', Date.now())
  }
};

app.use(express.static('public', options));

You can have more than one static directory per app.

app.use(express.static('public'));
app.use(express.static('uploads'));
app.use(express.static('files'));

For more details about serve-static and its options, visit the serve-static documentation.

Third-party middleware

Express is a routing and middleware web framework with minimal functionality of its own. Functionality to Express apps are added via third-party middleware.

Install the node module for the required functionality and loaded it in your app at the application level or at the router level.

In the following example, cookie-parser, a cookie parsing middleware is installed and loaded in the app.

$ npm install cookie-parser
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');

// load the cookie parsing middleware
app.use(cookieParser());

See Third-party middleware for a partial list of third-party middleware commonly used with Express.