Як отримати шлях запиту з експрес-об'єктом req


158

Я використовую express + node.js і у мене є об'єкт req, запитом у браузері є / рахунок, але коли я реєструю req.path, я отримую '/' --- не '/ 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 є / коли це має бути / рахунок ??


2
TypeError: Cannot read property 'path' of undefined
chovy

req.route.path правильно і документально тут . Яку версію Express ви використовуєте?
zemirco

У мене те саме питання. req.routeне визначено. Я використовую експрес 3.4.4. Що може призвести до невизначеності маршруту?
davidpfahler

@vinayr req.route.path як і раніше дає мені / створити замість / quizzes / create, яка є цілою URL-адресою
Sandip Subedi

Це цілеспрямована поведінка. І вам слід прийняти це. Ваш обробник повинен дбати не про повний шлях, а лише про "локальну" частину шляху. Це частина після шляху, на яку вона була встановлена. Це полегшує повторне використання функції обробника в інших контекстах.
Штійн де Вітт

Відповіді:


234

Потрапивши трохи в гру, ви повинні використовувати:

console.log(req.originalUrl)


3
Я думаю, що це має щось спільне з позиціонуванням проміжного програмного забезпечення, але ви правильно, це не має сенсу.
Менцтруаль

1
Це, безумовно, програмне забезпечення. Це трапляється і з додатковими маршрутизаторами в Express 4. Коли будь-який встановлений на певному шляху, всередині себе він робить вигляд, що він відходить від кореня. Це приємно для ізоляції, але хитро, коли ви не знаєте, як отримати те, що було початковою повною цінністю. Дякуємо, що опублікували це!
juanpaco

3
Кожен, хто потрапляє сюди на 4.0, req.url розроблений таким чином, що він може бути змінений середнім програмним забезпеченням для цілей перенаправлення, і req.path може бракувати точки кріплення залежно від місця його виклику. expressjs.com/uk/api.html#req.originalUrl
Christian Davis

3
Якщо ви не хочете, щоб рядок запитів включав:const path = req.originalUrl.replace(/\?.*$/, '');
Адам Рейс

1
Попередження: Це хибна відповідь, заснована на питанні про ОП. Це також поверне рядок запиту (наприклад? 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

1
Будьте уважні, якщо ви робите перевірку на цю URL-адресу, щоб також було включено чек на проділ, якщо він дійсний у вашому додатку. (тобто перевірка /demoтакож повинна потенційно перевірятися /demo/).
Винай

Якщо ви не хочете, щоб рядок запиту включав: const path = req.originalUrl.replace (/\?.*$/, '');
Адам Рейс

req.pathце скорочення url.parse(req.url).pathnameта це має бути прийнята відповідь
sertsedat

1
@sertsedat Неправильно. req.pathдає відносний шлях до того, де встановлено вашу програму. Якщо він встановлений у корені, це правильне, але для шляху /my/pathв межах додатка, встановленого на /my, req.urlбуде дано /path.
Штійн де Вітт

21

Для доповнення, ось приклад, розширений з документації, який добре описує все, що вам потрібно знати про доступ до шляхів / URL-адрес у всіх випадках з експресом:

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;


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 є / коли це має бути / рахунок ??

Причиною цього є те, що 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якщо вхід вдалий
Ryan Wu

Це чудово працює з універсальним кодом, оскільки він відповідає специфікації Location . Менше запам'ятовувати речі та простіше провести тестування на клієнті та сервері.
Камберлен

req.pathце лише псевдонім дляurl.parse(req.url).pathname
mhodges

8

Для версії 4.x тепер ви можете використовувати req.baseUrlдодаток, req.pathщоб отримати повний шлях. Наприклад, зараз ОП зробить щось на кшталт:

//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();
  }
});

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.