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 ??


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)


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

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;


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!

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

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

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.