express reqオブジェクトでリクエストパスを取得する方法


158

私はexpress + node.jsを使用していて、reqオブジェクトがありますが、ブラウザーでのリクエストは/ accountですが、req.pathをログに記録すると、「/」ではなく「/」が表示されます。

  //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は/である必要があります/ accountである必要がありますか?


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

req.route.pathは正しく、ここに記載されています。Expressのどのバージョンを使用していますか?
zemirco 2012

同じ問題が発生しています。req.route未定義です。エクスプレス3.4.4を使用しています。ルートが未定義になる原因は何ですか?
davidpfahler 2013年

@vinayr req.route.pathでも、/ quizzes / createではなく/ createが引き続き表示されます。これはURL全体です
Sandip Subedi

これは意図された動作です。そして、あなたはそれを受け入れるべきです。ハンドラーは完全なパスを気にする必要はなく、パスの「ローカル」部分のみを気にする必要があります。それはそれがマウントされたパスの後の部分です。これにより、ハンドラー関数を他のコンテキストで再利用しやすくなります。
Stijn de Witt 2017

回答:


234

少し遊んだ後は、次のようにしてください。

console.log(req.originalUrl)


3
ミドルウェアの位置付けと関係があると思いますが、正解です。意味がありません。
Menztrual 2012

1
それは間違いなくミドルウェアです。これは、Express 4の追加のルーターでも発生します。どちらかが特定のパスからマウントされている場合、それ自体の内部では、ルートから外れているように見せかけます。これは分離に適していますが、元の完全な値を取得する方法がわからない場合は注意が必要です。これを投稿してくれてありがとう!
juanpaco

3
4.0にアクセスする人は誰でも、req.urlは再ルーティングの目的でミドルウェアによって変更できるように設計されており、req.pathは呼び出される場所によってはマウントポイントが欠落している可能性があります。expressjs.com/en/api.html#req.originalUrl
クリスチャンデイビス

3
クエリ文字列を含めたくない場合:const path = req.originalUrl.replace(/\?.*$/, '');
Adam Reis

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

1
このURLに対してチェックを行う場合は、アプリで有効な場合、末尾のスラッシュのチェックも含めるように注意してください。(つまり、をチェックすると、/demoもチェックされる可能性があります/demo/)。
Vinay

クエリ文字列を含めたくない場合:const path = req.originalUrl.replace(/\?.*$/、 '');
Adam Reis、

req.path省略形でurl.parse(req.url).pathname、これは受け入れ答えなければなりません
sertsedat

1
@sertsedat不正解です。req.pathアプリがマウントされている場所への相対パスを提供します。それがルートにマウントされている場合、これは正しいのですが、パスのためよりも/my/path、アプリがで取り付けられた内/myreq.url提供します/path
Stijn de Witt

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;


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は/である必要があります/ 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ログインが成功した場合に使用
Ryan Wu

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

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.