jak uzyskać ścieżkę żądania z obiektem express req

158

Używam express + node.js i mam obiekt req, żądanie w przeglądarce to / account, ale kiedy loguję req.path, otrzymuję „/” --- nie „/ 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 to / kiedy powinno być / account ??

chovy
źródło
2
TypeError: Cannot read property 'path' of undefined
chovy
req.route.path jest poprawna i udokumentowana tutaj . Z jakiej wersji ekspresu korzystasz?
zemirco
Mam ten sam problem. req.routejest niezdefiniowana. Używam Express 3.4.4. Co może spowodować niezdefiniowanie trasy?
davidpfahler
@vinayr req.route.path nadal daje mi / create zamiast / quizzes / create, czyli cały adres URL
Sandip Subedi
To jest zamierzone zachowanie. I powinieneś to przyjąć. Twój przewodnik nie powinien przejmować się pełną ścieżką, a jedynie „lokalną” częścią ścieżki. To część po ścieżce, na której został zamontowany. To sprawia, że ​​funkcja obsługi jest łatwiejsza do ponownego użycia w innych kontekstach.
Stijn de Witt

Odpowiedzi:

234

Po odrobinie zabawy powinieneś użyć:

console.log(req.originalUrl)

Menztrual
źródło
3
Myślę, że ma to coś wspólnego z pozycjonowaniem oprogramowania pośredniego, ale masz rację, to nie ma sensu.
Menztrual
1
To zdecydowanie oprogramowanie pośredniczące. Dzieje się tak również w przypadku dodatkowych routerów w Express 4. Kiedy któryś z nich jest zamontowany poza określoną ścieżką, wewnątrz siebie udaje, że znajduje się poza korzeniem. To miłe dla izolacji, ale trudne, gdy nie wiesz, jak uzyskać oryginalną pełną wartość. Dzięki za opublikowanie tego!
juanpaco
3
Każdy, kto dostanie się tutaj w wersji 4.0, req.url jest zaprojektowany tak, aby był modyfikowalny przez oprogramowanie pośredniczące w celu przekierowania, a w req.path może brakować punktów montowania w zależności od tego, gdzie jest wywoływany. expressjs.com/en/api.html#req.originalUrl
Christian Davis,
3
Jeśli nie chcesz, aby ciąg zapytania zawierał:const path = req.originalUrl.replace(/\?.*$/, '');
Adam Reis,
1
Ostrzeżenie: jest to myląca odpowiedź oparta na pytaniu PO. Spowoduje to również zwrócenie ciągu zapytania (np.? A = b & c = 5), jeśli był obecny. Zobacz expressjs.com/en/api.html#req.originalUrl
Ciabaros
60

W niektórych przypadkach powinieneś użyć:

req.path

To daje ścieżkę zamiast pełnego żądanego adresu URL. Na przykład, jeśli interesuje Cię tylko strona żądana przez użytkownika, a nie wszystkie rodzaje parametrów, adres URL:

/myurl.htm?allkinds&ofparameters=true

req.path da Ci:

/myurl.html
DivZero
źródło
1
Uważaj, jeśli sprawdzasz ten adres URL, aby uwzględnić również sprawdzenie końcowego ukośnika, jeśli jest on prawidłowy w Twojej aplikacji. (tj. sprawdzanie /demopowinno również potencjalnie sprawdzać /demo/).
Vinay
Jeśli nie chcesz, aby ciąg zapytania zawierał: const path = req.originalUrl.replace (/\?.*$/, '');
Adam Reis,
req.pathjest skrótem url.parse(req.url).pathnamei to powinna być akceptowana odpowiedź
sertsedat
1
@sertsedat Niepoprawne. req.pathpodaje względną ścieżkę do miejsca zainstalowania aplikacji. Jeśli jest zamontowany u nasady niż jest to poprawne, ale na ścieżce /my/path, w ciągu aplikacja zamontowany /my, req.urldadzą /path.
Stijn de Witt
21

Jako uzupełnienie, oto przykład rozwinięty z dokumentacji, który ładnie opakowuje wszystko, co musisz wiedzieć o dostępie do ścieżek / adresów URL we wszystkich przypadkach za pomocą 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()
})

Na podstawie: https://expressjs.com/en/api.html#req.originalUrl

Wniosek: Jak odpowiedź c1moore za stwierdza powyżej, zastosowanie:

var fullPath = req.baseUrl + req.path;
Ciabaros
źródło
11

Powinno być:

req.url

express 3.1.x

Jürgen Paul
źródło
req.url nie jest natywną właściwością Express, jest dziedziczona z modułu 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 to / kiedy powinno być / account ??

Powodem tego jest to, że Express odejmuje ścieżkę, na której jest zamontowana funkcja obsługi, co ma miejsce '/account'w tym przypadku.

Dlaczego oni to robią?

Ponieważ ułatwia to ponowne użycie funkcji obsługi. Możesz utworzyć funkcję obsługi, która wykonuje różne rzeczy dla req.path === '/'i req.path === '/goodbye'na przykład:

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

Następnie możesz zamontować go na wielu punktach końcowych:

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

Dający:

/world           ==>  Hello there!
/world/goodbye   ==>  Farewell!
/aliens          ==>  Hello there!
/aliens/goodbye  ==>  Farewell!
Stijn de Witt
źródło
9

Jeśli naprawdę chcesz uzyskać tylko „ścieżkę” bez zapytań, możesz użyć urlbiblioteki do analizy i uzyskać tylko część ścieżki adresu 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();
    }
});
Murat Çorlu
źródło
dokładnie tego chcę. Użyj go, req.query.refjeśli logowanie się powiedzie
Ryan Wu
Działa to dobrze z kodem uniwersalnym, ponieważ jest zgodny ze specyfikacją lokalizacji . Mniej rzeczy do zapamiętania i łatwiejsze do testowania jednostkowego na kliencie i serwerze.
cchamberlain
req.pathjest po prostu aliasem dlaurl.parse(req.url).pathname
mhodges
8

W wersji 4.x możesz teraz użyć req.baseUrldodatku do, req.pathaby uzyskać pełną ścieżkę. Na przykład OP zrobiłby teraz coś takiego:

//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
źródło
5

req.route.path działa dla mnie

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

po uruchomieniu w konsoli widzę następujący komunikat i uzyskuję doskonały wynik w przeglądarce.

Express server listening on port 3000 in development mode
A call to route: /plants
Request type: get
Bahman.A.
źródło