Передача переменных следующему промежуточному программному обеспечению с помощью next () в Express.js

201

Ну, мой вопрос: я хочу передать некоторую переменную из первого промежуточного программного обеспечения в другое промежуточное программное обеспечение, и я попытался сделать это, но было « req.somevariableзадано как« неопределенное »».


//app.js
..
app.get('/someurl/', middleware1, middleware2)
...

////middleware1
...
some conditions
...
res.somevariable = variable1;
next();
...

////middleware2
...
some conditions
...
variable = req.somevariable;
...
user2791897
источник
Должно сработать. Если это не опечатка в вопросе, вы, вероятно, потерпите неудачу, потому что вы присваиваете значение resв middleware1 и пытаетесь получить его из reqmiddleware2.
Андреас Халтгрен
Thankz @AndreasHultgren
user2791897
Local variables are available in middleware via req.app.locals expressjs.com/pt-br/api.html#app.locals
Ронни Ройстон,

Ответы:

202

Прикрепите вашу переменную к reqобъекту, а не res.

Вместо того

res.somevariable = variable1;

Есть:

req.somevariable = variable1;

Как уже отмечали другие, res.localsэто рекомендуемый способ передачи данных через промежуточное ПО.

Amberlamps
источник
13
использовать res.locals.variable = var; см. другой ответ
Годза
1
чтобы получить переменную, используйте req.res.locals.variable в следующей функции промежуточного программного обеспечения
Уильям Ву
3
@WilliamWu его res.locals, нет req.res.locals.
cchamberlain
2
res.locals.myVarэто путь
Ясонсеминара
449

Это то, для чего предназначен объект res.locals . Установка переменных непосредственно в объекте запроса не поддерживается и не документируется. res.locals гарантированно сохраняет состояние в течение срока действия запроса.

res.locals

Объект, который содержит локальные переменные ответа, ограниченные областью запроса и, следовательно, доступные только для представлений, представленных в течение этого цикла запрос / ответ (если есть). В противном случае это свойство идентично app.locals.

Это свойство полезно для предоставления информации уровня запроса, такой как имя пути запроса, аутентифицированный пользователь, настройки пользователя и так далее.

app.use(function(req, res, next) {
    res.locals.user = req.user;  
    res.locals.authenticated = !req.user.anonymous;
    next();
});

Чтобы получить переменную в следующем промежуточном программном обеспечении:

app.use(function(req, res, next) {
    if (res.locals.authenticated) {
        console.log(res.locals.user.id);
    }
    next();
});
cchamberlain
источник
67
Не знаю , почему это не общепринятый ответ, это документированы способ установки переменных из промежуточного программного обеспечения по всему запросу.
Сэм Холмс
11
res.locals предназначен для использования представлениями , которые в конечном итоге отображаются в течение жизненного цикла запроса, это то, что говорится в документации. Если вы не используете представления, то слишком сложно помещать объекты в объект localals, и это не является соглашением. В этих случаях я склоняюсь к тому, чтобы люди придерживались соглашения, чтобы мы могли снизить когнитивную нагрузку, изучая такие понятия, как Express или запрашивая жизненные циклы.
real_ate
2
@real_ate, который является основным использованием res.locals, однако не затрагивает вопрос OPs. Передача переменных области запроса в будущее промежуточное программное обеспечение иногда является необходимостью, когда я сталкивался с такой ситуацией, как правило, вокруг проверки подлинности пользователя в раннем промежуточном программном обеспечении, которое устанавливает утверждения, которые маршрутизируются в промежуточном промежуточном программном обеспечении.
cchamberlain
14
Экспресс-документация для написания промежуточного программного обеспечения устанавливает переменные на reqобъекте expressjs.com/en/guide/writing-middleware.html . Посмотрите на разделMiddleware function requestTime
Сом
3
К счастью, @goonerify - это не то, как работает ответ. Ответы передаются путем вызова функционального свойства объекта ответа, такого как res.json({})и т. Д. res.locals, Которое доступно только на бэкэнде в течение срока действия запроса. expressjs.com/en/5x/api.html
cchamberlain
22

Я не думаю, что лучшая практика будет передавать переменную, как req.YOUR_VAR. Вы можете рассмотреть req.YOUR_APP_NAME.YOUR_VARили req.mw_params.YOUR_VAR.

Это поможет вам избежать перезаписи других атрибутов.

Обновление 31 мая 2020 г.

Res.locals - это то, что вы ищете, объект находится в области запроса.

Объект, который содержит локальные переменные ответа, ограниченные областью запроса и, следовательно, доступные только для представлений, представленных в течение этого цикла запрос / ответ (если есть). В противном случае это свойство идентично app.locals.

Это свойство полезно для предоставления информации уровня запроса, такой как имя пути запроса, аутентифицированный пользователь, настройки пользователя и так далее.

Дорон Сигал
источник
2
Как вы предлагаете установить req.YOUR_APP_NAME = {}изначально? Просто попробуйте написать, req.YOUR_APP_NAME.someVarвы получите сообщение об ошибке, поскольку req.YOUR_APP_NAMEоно еще не определено.
Kousha
2
@Kousha Вы можете написать промежуточное программное обеспечение маршрутизатора в верхней части скрипта маршрутизации:router.use(function(req,res,next){req.YOUR_APP_NAME = {};next()})
Томас
Есть ли способ передать его в качестве параметра с помощью функции next ()? как следующий (myObj)
philx_x
1
@ Kousha - Ваша неопределенная ошибка не имеет ничего общего с express, вы пытаетесь присвоить свойство несуществующему объекту. Обычно для этого вы бы использовали req.APP_NS = req.APP_NS || {}; req.APP_NS.somevar = 'value'.
cchamberlain
1
@philx_x, если вы передадите какой-либо параметр в nextфункцию, он вызовет экспресс-обработчик ошибок и выпадет. проверьте документы.
Merl
7

Это потому reqи resдва разных объекта.

Вам нужно искать свойство в том же объекте, к которому вы его добавили.

SLaks
источник
3

Уловка довольно проста ... Цикл запросов все еще в значительной степени жив. Вы можете просто добавить новую переменную, которая создаст временную, вызывая

app.get('some/url/endpoint', middleware1, middleware2);

Так как вы можете обработать ваш запрос в первом промежуточном программном обеспечении

(req, res, next) => {
    var yourvalue = anyvalue
}

В промежуточном программном обеспечении 1 вы обрабатываете свою логику и сохраняете свои значения, как показано ниже:

req.anyvariable = yourvalue

В промежуточном программном обеспечении 2 вы можете поймать это значение из промежуточного программного обеспечения 1, выполнив следующие действия:

(req, res, next) => {
    var storedvalue = req.yourvalue
}
Delino
источник
1

Как упомянуто выше, res.locals - хороший (рекомендуемый) способ сделать это. Смотрите здесь краткое руководство о том, как это сделать в Express.

nax3t
источник