Что в действительности означает middleware и app.use в Expressjs? - PullRequest
208 голосов
/ 07 сентября 2011

Почти каждое приложение Express, которое я вижу, имеет оператор app.use для промежуточного программного обеспечения, но я не нашел четкого и краткого объяснения того, что на самом деле является промежуточным ПО и что делает оператор app.use.Даже сами экспресс-документы немного расплывчаты в этом.Можете ли вы объяснить эти понятия для меня, пожалуйста?

Ответы [ 9 ]

101 голосов
/ 07 сентября 2011

* промежуточный слой 1002 *

Я на полпути к разделению концепции промежуточного программного обеспечения в новом проекте.

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

// express
var app = express();
// middleware
var stack = middleware();

Затем вы можете добавить слои в стек промежуточного программного обеспечения, вызвав .use

// express
app.use(express.static(..));
// middleware
stack.use(function(data, next) {
  next();
});

Слой в стеке промежуточного программного обеспечения - это функция, которая принимает n параметров (2 для экспресс, req & res) и функцию next.

Промежуточное программное обеспечение ожидает, что слой выполнит некоторые вычисления, увеличит параметры и затем вызовет next.

Стек ничего не делает, если вы с ним не справитесь. Express будет обрабатывать стек каждый раз, когда поступающий HTTP-запрос перехватывается на сервере. С промежуточным ПО вы обрабатываете стек вручную.

// express, you need to do nothing
// middleware
stack.handle(someData);

Более полный пример:

var middleware = require("../src/middleware.js");

var stack = middleware(function(data, next) {
    data.foo = data.data*2;
    next();
}, function(data, next) {
    setTimeout(function() {
        data.async = true;
        next();
    }, 100)
}, function(data) {
    console.log(data);
});

stack.handle({
    "data": 42
})

В экспресс-выражениях вы просто определяете стек операций, которые вы хотите обработать для каждого входящего HTTP-запроса.

С точки зрения экспресса (а не соединения) у вас есть глобальное промежуточное ПО и промежуточное ПО для конкретных маршрутов. Это означает, что вы можете прикреплять стек промежуточного программного обеспечения к каждому входящему HTTP-запросу или только к HTTP-запросам, которые взаимодействуют с определенным маршрутом.

Расширенные примеры экспресс и промежуточного программного обеспечения:

// middleware 

var stack = middleware(function(req, res, next) {
    users.getAll(function(err, users) {
        if (err) next(err);
        req.users = users;
        next();  
    });
}, function(req, res, next) {
    posts.getAll(function(err, posts) {
        if (err) next(err);
        req.posts = posts;
        next();
    })
}, function(req, res, next) {
    req.posts.forEach(function(post) {
        post.user = req.users[post.userId];
    });

    res.render("blog/posts", {
        "posts": req.posts
    });
});

var app = express.createServer();

app.get("/posts", function(req, res) {
   stack.handle(req, res); 
});

// express

var app = express.createServer();

app.get("/posts", [
    function(req, res, next) {
        users.getAll(function(err, users) {
            if (err) next(err);
            req.users = users;
            next();  
        });
    }, function(req, res, next) {
        posts.getAll(function(err, posts) {
            if (err) next(err);
            req.posts = posts;
            next();
        })
    }, function(req, res, next) {
        req.posts.forEach(function(post) {
            post.user = req.users[post.userId];
        });

        res.render("blog/posts", {
            "posts": req.posts
        });
    }
], function(req, res) {
   stack.handle(req, res); 
});
55 голосов
/ 07 сентября 2011

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

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

27 голосов
/ 18 мая 2015

Я добавляю поздний ответ, чтобы добавить что-то, не упомянутое в предыдущих ответах.

К настоящему времени должно быть ясно, что промежуточное ПО выполняет функции, выполняемые между клиентским запросом и серверным ответом . Наиболее часто используемые функции промежуточного программного обеспечения - это управление ошибками, взаимодействие с базой данных, получение информации из статических файлов или других ресурсов. Для перемещения по стеку промежуточного программного обеспечения должен быть вызван следующий обратный вызов, вы можете увидеть его в конце функции промежуточного программного обеспечения, чтобы перейти к следующему шагу в потоке.

Вы можете использовать подход app.use и иметь поток , подобный этому :

var express = require('express'),
    app = express.createServer(),                                                                                                                                                 
    port = 1337;

function middleHandler(req, res, next) {
    console.log("execute middle ware");
    next();
}

app.use(function (req, res, next) {
    console.log("first middle ware");                                                                                                             
    next();
});

app.use(function (req, res, next) {
    console.log("second middle ware");                                                                                                             
    next();
});

app.get('/', middleHandler, function (req, res) {
    console.log("end middleware function");
    res.send("page render finished");
});

app.listen(port);
console.log('start server');

но вы также можете использовать другой подход и передавать каждое промежуточное ПО в качестве аргументов функции. Вот пример с веб-сайта MooTools Nodejs , где midleware получает поток Twitter, Github и Blog перед отправкой response клиенту. Обратите внимание, как функции передаются в качестве аргументов в app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){. Использование app.get будет вызываться только для запросов GET, app.use будет вызываться для всех запросов.

// github, twitter & blog feeds
var githubEvents = require('./middleware/githubEvents')({
    org: 'mootools'
});
var twitter = require('./middleware/twitter')();
var blogData = require('./blog/data');
function getLatestBlog(req, res, next){
    blogData.get(function(err, blog) {
        if (err) next(err);
        res.locals.lastBlogPost = blog.posts[0];
        next();
    });
}

// home
app.get('/', githubEvents, twitter, getLatestBlog, function(req, res){
    res.render('index', {
        title: 'MooTools',
        site: 'mootools',
        lastBlogPost: res.locals.lastBlogPost,
        tweetFeed: res.locals.twitter
    });
});
14 голосов
/ 05 января 2018

expressjs гид имеет довольно аккуратный ответ на ваш вопрос, я настоятельно рекомендую вам прочитать его, я выкладываю небольшой фрагмент руководства, руководство довольно хорошее.

Написаниепромежуточное программное обеспечение для использования в приложениях Express

Обзор

Промежуточное программное обеспечение - это функции, которые имеют доступ к объекту запроса ( req ), объект ответа ( res ) и следующая функция в цикле запрос-ответ приложения.Следующая функция - это функция в маршрутизаторе Express, которая при вызове выполняет промежуточное ПО, которое следует за текущим промежуточным ПО.

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

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

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

enter image description here

Пример

Вот пример простогоЭкспресс приложение «Hello World».В оставшейся части этой статьи будут определены и добавлены две функции промежуточного программного обеспечения для приложения: одна называется myLogger , которая печатает простое сообщение журнала, а другая - requestTime 1 , которая отображаетметка времени HTTP-запроса.

var express = require('express')
var app = express()

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

app.listen(3000)   

Функция промежуточного программного обеспечения myLogger

Вот простой пример функции промежуточного программного обеспечения, называемой «myLogger».Эта функция просто печатает «LOGGED», когда через него проходит запрос к приложению.Функция промежуточного программного обеспечения назначается переменной с именем myLogger.

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

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

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

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 () .


Этот пост будет содержать только промежуточное ПО myLogger, для дальнейшего поста вы можете перейти к оригинальному руководству по expressjs здесь .
8 голосов
/ 17 февраля 2018

===== Очень очень простое объяснение =====

Промежуточное программное обеспечение часто используется в контексте инфраструктуры Express.js и является фундаментальной концепцией для node.js. Короче говоря, это в основном функция, которая имеет доступ к объектам запросов и ответов вашего приложения. Я бы хотел подумать об этом - это серия «проверок / предварительных проверок», через которые проходит запрос, прежде чем он будет обработан приложением. Например, Middlewares было бы целесообразно определить, аутентифицирован ли запрос, прежде чем он перейдет в приложение, и вернуть страницу входа в систему, если запрос не аутентифицирован, или для регистрации каждого запроса. Доступно множество сторонних промежуточных программ, обеспечивающих разнообразные функциональные возможности.

Простой пример Middleware:

var app = express();
app.use(function(req,res,next)){
    console.log("Request URL - "req.url);
    next();
}

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

Несколько промежуточных программных Gotchas:

  1. Порядок промежуточного программного обеспечения в вашем приложении имеет значение, так как запрос будет проходить через каждого из них в последовательном порядке.
  2. Если вы забудете вызвать метод next () в вашей функции промежуточного программного обеспечения, это может остановить обработку вашего запроса.
  3. Любое изменение объектов req и res в функции промежуточного программного обеспечения сделает это изменение доступным для других частей приложения, использующего req и res
7 голосов
/ 24 февраля 2016

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

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

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

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

5 голосов
/ 05 июля 2016

Промежуточное программное обеспечение - это подмножество связанных функций, вызываемых уровнем маршрутизации Express js до вызова пользовательского обработчика.Функции промежуточного программного обеспечения имеют полный доступ к объектам запроса и ответа и могут изменять любой из них.

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

1 голос
/ 20 марта 2016

Не усложняйте, приятель!

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

С моей точки зрения, промежуточное программное обеспечение действует как вспомогательные или вспомогательные функции, но его активация и использование полностью необязательны с использованием app.use('path', /* define or use builtin middleware */), который не хочет, чтобы мы писали некоторыекод для выполнения очень распространенных задач, необходимых для каждого HTTP-запроса нашего клиента, таких как обработка файлов cookie, токенов CSRF и ..., которые очень распространены в большинстве приложений , поэтому промежуточное ПО может помочь нам сделать все это для каждого HTTP-запросанаш клиент в некотором стеке, последовательности или порядке операций затем предоставляет результат процесса как единое целое клиентского запроса .

Пример:

Прием запросов клиентов и предоставление обратных ответовдля них в соответствии с их запросами природа веб-сервера.

Представьте себе, если мы предоставляем разрешениеПонас просто "Привет, мир!"Текст для запроса GET HTTP к корневому URI нашего веб-сервера является очень простым сценарием и больше ничего не требует, но вместо этого, если мы проверяем текущего пользователя, вошедшего в систему, а затем отвечаем «Привет, Имя пользователя!»в этом случае требуется нечто большее, чем обычно, в этом случае нам необходимо промежуточное программное обеспечение для обработки всех метаданных запроса клиента и предоставления нам идентификационной информации, полученной из запроса клиента, а затем в соответствии с этой информацией мы можем однозначно идентифицировать нашего текущего пользователя и получить возможность ответить на него/ ей с некоторыми связанными данными.

Надеюсь, это кому-нибудь поможет!

0 голосов
/ 02 января 2019

В самом простом термине, если я хочу объяснить это так, я узнаю это из ускоренного курса traversymedia youtube channel.Итак, промежуточное ПО - это функция, которая выполняется после того, как вы выполняете вызов на ваш маршрут следующим образом.

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

app.use(logger);

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...