Интересно, как получить доступ к объекту req, если в обратном вызове нет параметра req.

Это сценарий :
В ExpressJs у меня есть общая функция, она используется для обработки чего-либо с объектом req, но не передает в него req.

module.exports = {
    get: function(){
        var req = global.currentRequest;
        //do something...
    }
}

Мое текущее решение состоит в том, что я пишу промежуточное ПО для всех запросов, я помещаю 'req' в глобальную переменную, затем я могу получить доступ к 'req' везде с помощью 'global.currentRequest'.

// in app.js
app.use(function (req, res, next) {
    global.currentRequest= req;
    next();
});

Но не знаю, хорошо ли? Есть ли у кого-нибудь предложения?
Большое спасибо!

15
Sky 6 Сен 2016 в 05:05

3 ответа

Лучший ответ

Единственный правильный способ - передать объект req в качестве аргумента всем функциям, которым он нужен.

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

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

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

Есть некоторые обстоятельства, при которых вы можете использовать замыкание для «захвата» желаемого объекта req, а затем использовать его во внутренних функциях, не передавая его этим внутренним функциям, но это не похоже на то, что это ваша функция состав. Нам нужно было бы увидеть намного больше вашего реального / фактического кода, чтобы знать, возможно ли это или нет.

8
jfriend00 8 Сен 2016 в 05:19

Вместо использования глобальных переменных, что никогда не бывает лучшей идеей, вы можете обернуть module.exports, чтобы принять req в качестве параметра.

module.exports = function (req) {
    function get() {
        // it has access to req.
        console.log(req);
    }

    return get;
}

И вы можете require вышеуказанный модуль как

app.use(function (req, res, next) {
    const mod = require('/path/to/module')(req);
    next();
});
-1
Swaraj Giri 6 Сен 2016 в 03:33

На самом деле это возможно с помощью чего-то вроде global-request-context

Здесь используется zone.js, позволяющая сохранять переменные в асинхронных задачах.

1
Tom Esterez 26 Мар 2019 в 02:04