Перейти к содержанию

Написание кода промежуточных обработчиков

Обзор

Функции промежуточной обработки (middleware) - это функции, имеющие доступ к объекту запроса (req), объекту ответа (res) и к следующей функции промежуточной обработки в цикле "запрос-ответ" приложения. Следующая функция промежуточной обработки, как правило, обозначается переменной next.

Функции промежуточной обработки могут выполнять следующие задачи:

  • Выполнение любого кода.
  • Внесение изменений в объекты запросов и ответов.
  • Завершение цикла "запрос-ответ".
  • Вызов следующего промежуточного обработчика из стека.

Если текущая функция промежуточной обработки не завершает цикл "запрос-ответ", она должна вызвать next() для передачи управления следующей функции промежуточной обработки. В противном случае запрос зависнет.

Далее приводится пример простого приложения Ниже Express "Hello World", для которого будут определены две функции промежуточных обработчиков:

1
2
3
4
5
6
7
8
var express = require('express');
var app = express();

app.get('/', function (req, res) {
    res.send('Hello World!');
});

app.listen(3000);

Разработка

Ниже приводится простой пример промежуточного обработчика "myLogger". Эта функция печатает слово "LOGGED" при прохождении запроса, адресованного приложению, через приложение. Данная функция промежуточного обработчика присвоена переменной с именем myLogger.

1
2
3
4
var myLogger = function (req, res, next) {
    console.log('LOGGED');
    next();
};

Обратите внимание на вызов next() выше. Вызов этой функции активирует следующую функцию промежуточной обработки в приложении. Функция next() не является частью Node.js или Express API, но представляет собой третий аргумент, передаваемый в функцию промежуточного обработчика. Функция next() могла бы иметь любое имя, но, согласно стандарту, она всегда называется "next". Во избежание путаницы, рекомендуется всегда придерживаться данного стандарта.

Для того чтобы загрузить функцию промежуточного обработчика вызовите app.use() с указанием соответствующей функции. Например, приведенный ниже код загружает функцию промежуточного обработчика myLogger перед маршрутом к корневому расположению (/).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
var express = require('express');
var app = express();

var myLogger = function (req, res, next) {
    console.log('LOGGED');
    next();
};

app.use(myLogger);

app.get('/', function (req, res) {
    res.send('Hello World!');
});

app.listen(3000);

Каждый раз при получении запроса приложение выводит на терминал сообщение "LOGGED".

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

Если myLogger загружается после маршрута к корневому расположению, запрос никогда не достигает его, и приложением не выводится сообщение "LOGGED", поскольку обработчик маршрута корневого пути завершает цикл "запрос-ответ".

Промежуточный обработчик myLogger всего лишь выводит сообщение, затем передает запрос далее, следующему промежуточному обработчику в стеке, путем вызова функции next().

В следующем примере выполняется добавление свойства requestTime в объект запроса. Назовем эту функцию промежуточного обработчика "requestTime".

1
2
3
4
var requestTime = function (req, res, next) {
    req.requestTime = Date.now();
    next();
};

Теперь приложением используется функция промежуточного обработчика requestTime. Кроме того, функция обратного вызова маршрута корневого расположения (пути) использует свойство, добавленную функций промежуточного обработчика в req (объект запроса).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
var express = require('express');
var app = express();

var requestTime = function (req, res, next) {
    req.requestTime = Date.now();
    next();
};

app.use(requestTime);

app.get('/', function (req, res) {
    var responseText = 'Hello World!<br>';
    responseText +=
        '<small>Requested at: ' +
        req.requestTime +
        '</small>';
    res.send(responseText);
});

app.listen(3000);

Если запрос адресован корневому каталогу приложения, приложение выводит на экран системное время запроса в браузере.

Благодаря наличию доступа к объекту запроса, объекту ответа, следующей функции промежуточного обработчика в стеке и к API Node.js в целом, возможности, связанные с промежуточными обработчиками, являются бесконечными.

Дополнительная информация о промежуточных обработчиках Express содержится в разделе Использование промежуточных обработчиков Express.