как получить путь запроса с помощью экспресс-объекта req

158

Я использую express + node.js и у меня есть объект req, запрос в браузере - / account, но когда я захожу в req.path, я получаю '/' --- not '/ account'.

  //auth required or redirect
  app.use('/account', function(req, res, next) {
    console.log(req.path);
    if ( !req.session.user ) {
      res.redirect('/login?ref='+req.path);
    } else {
      next();
    }
  });

req.path is / когда это должно быть / account?

chovy
источник
2
TypeError: Cannot read property 'path' of undefined
Чови
req.route.path является правильным и задокументированным здесь . Какую версию экспресс вы используете?
Zemirco
У меня та же проблема. req.routeне определено Я использую экспресс 3.4.4. Что может привести к тому, что маршрут будет неопределенным?
Давидпфахлер
@vinayr req.route.path по-прежнему дает мне / create вместо / quizzes / create, то есть весь URL-адрес
Sandip Subedi
Это намеренное поведение. И ты должен принять это. Ваш обработчик должен заботиться не о полном пути, а только о «локальной» части пути. Это часть пути, по которой он был установлен. Это делает функцию обработчика более легкой для повторного использования в других контекстах.
Стейн де Витт

Ответы:

234

После небольшой игры, вы должны использовать:

console.log(req.originalUrl)

Menztrual
источник
3
Я думаю, что это как-то связано с позиционированием промежуточного программного обеспечения, но вы правы, это не имеет смысла.
Menztrual
1
Это определенно промежуточное ПО. Это происходит и с дополнительными маршрутизаторами в Express 4. Когда любой из них монтируется вне заданного пути, внутри себя он притворяется, что он вне корня. Это хорошо для изоляции, но сложно, когда вы не знаете, как получить первоначальную полную стоимость. Спасибо за публикацию этого!
Джуанпако
3
Любой, кто попадает сюда на 4.0, req.url спроектирован так, чтобы быть изменяемым промежуточным ПО для целей перенаправления, а в req.path могут отсутствовать точки монтирования в зависимости от того, где он вызывается. expressjs.com/en/api.html#req.originalUrl
Кристиан Дэвис,
3
Если вы не хотите, чтобы строка запроса включала:const path = req.originalUrl.replace(/\?.*$/, '');
Адам Рейс
1
Предупреждение: Это вводящий в заблуждение ответ, основанный на вопросе OP. Это также вернет строку запроса (например,? A = b & c = 5), если она присутствовала. См. Expressjs.com/en/api.html#req.originalUrl
Ciabaros,
60

В некоторых случаях вы должны использовать:

req.path

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

/myurl.htm?allkinds&ofparameters=true

req.path даст вам:

/myurl.html
DivZero
источник
1
Будьте внимательны, если вы делаете проверки по этому URL, чтобы включить проверку на косую черту, если она действительна в вашем приложении. (т.е. проверка /demoдолжна также потенциально проверять /demo/).
Vinay
Если вы не хотите включать строку запроса: const path = req.originalUrl.replace (/\?.*$/, '');
Адам Рейс
req.pathэто стенография url.parse(req.url).pathnameи это должен быть принятый ответ
серцедат
1
@sertsedat Неверно. req.pathдает вам относительный путь к вашему приложению. Если он смонтирован в корне, то это правильно, но для пути /my/path, в приложении, смонтированном в /my, req.urlдаст /path.
Стейн де Витт
21

В дополнение к этому, вот пример, расширенный из документации, которая хорошо описывает все, что вам нужно знать о доступе к путям / URL-адресам во всех случаях с помощью express:

app.use('/admin', function (req, res, next) { // GET 'http://www.example.com/admin/new?a=b'
  console.dir(req.originalUrl) // '/admin/new?a=b' (WARNING: beware query string)
  console.dir(req.baseUrl) // '/admin'
  console.dir(req.path) // '/new'
  console.dir(req.baseUrl + req.path) // '/admin/new' (full path without query string)
  next()
})

Основано на: https://expressjs.com/en/api.html#req.originalUrl

Вывод: как указано выше в ответе c1moore , используйте:

var fullPath = req.baseUrl + req.path;
Ciabaros
источник
11

Так должно быть:

req.url

экспресс 3.1.х

Юрген Пауль
источник
req.url не является собственным свойством Express, оно наследуется от http-модуля Node: expressjs.com/en/api.html#req.originalUrl
Megagator
9
//auth required or redirect
app.use('/account', function(req, res, next) {
  console.log(req.path);
  if ( !req.session.user ) {
    res.redirect('/login?ref='+req.path);
  } else {
    next();
  }
});

req.path is / когда это должно быть / account?

Причина этого заключается в том, что Express вычитает путь, по которому монтируется ваша функция обработчика, что '/account'в данном случае.

Почему они это делают?

Потому что это облегчает повторное использование функции-обработчика. Вы можете сделать функцию обработчика , которая делает разные вещи для req.path === '/'и req.path === '/goodbye', например:

function sendGreeting(req, res, next) {
  res.send(req.path == '/goodbye' ? 'Farewell!' : 'Hello there!')
}

Затем вы можете подключить его к нескольким конечным точкам:

app.use('/world', sendGreeting)
app.use('/aliens', sendGreeting)

Предоставление:

/world           ==>  Hello there!
/world/goodbye   ==>  Farewell!
/aliens          ==>  Hello there!
/aliens/goodbye  ==>  Farewell!
Стейн де Витт
источник
9

Если вы действительно хотите получить только «путь» без строки запроса, вы можете использовать urlбиблиотеку для анализа и получения только части пути в URL.

var url = require('url');

//auth required or redirect
app.use('/account', function(req, res, next) {
    var path = url.parse(req.url).pathname;
    if ( !req.session.user ) {
      res.redirect('/login?ref='+path);
    } else {
      next();
    }
});
Мурат Чорлу
источник
это именно то, что я хочу. Используйте его при req.query.refуспешном входе в систему
Райан Ву
Это прекрасно работает с универсальным кодом, поскольку соответствует спецификации Location . Меньше вещей для запоминания и проще для модульного тестирования на клиенте и сервере.
cchamberlain
req.pathэто просто псевдоним дляurl.parse(req.url).pathname
Mhodges
8

Для версии 4.x теперь вы можете использовать req.baseUrlв дополнение к, req.pathчтобы получить полный путь. Например, OP теперь будет делать что-то вроде:

//auth required or redirect
app.use('/account', function(req, res, next) {
  console.log(req.baseUrl + req.path);  // => /account

  if(!req.session.user) {
    res.redirect('/login?ref=' + encodeURIComponent(req.baseUrl + req.path));  // => /login?ref=%2Faccount
  } else {
    next();
  }
});
c1moore
источник
5

req.route.path работает на меня

var pool = require('../db');

module.exports.get_plants = function(req, res) {
    // to run a query we can acquire a client from the pool,
    // run a query on the client, and then return the client to the pool
    pool.connect(function(err, client, done) {
        if (err) {
            return console.error('error fetching client from pool', err);
        }
        client.query('SELECT * FROM plants', function(err, result) {
            //call `done()` to release the client back to the pool
            done();
            if (err) {
                return console.error('error running query', err);
            }
            console.log('A call to route: %s', req.route.path + '\nRequest type: ' + req.method.toLowerCase());
            res.json(result);
        });
    });
};

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

Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
Bahman.A
источник