Express.jsルーティング:オプションのスプラットパラメータ?


82

私は次のようなルートを持っています:

app.all('/path/:namedParam/*splat?',function(req,res,next){
  if(!req.params.length){
    // do something when there is no splat
  } else {
    // do something with splat
  }
});

ただし、これは機能しません。path/foo/bar電話をかけるとルートにヒットしますが、電話をかけるpath/fooと機能しません。

オプションのスプラットパラメータを持つことは可能ですか、それともこれを検出するために正規表現を使用する必要がありますか?

編集

より明確にするために、これが私が達成しようとしている要件です:

  • 最初と2番目のパラメータが必要です
  • 最初のパラメータは静的で、2番目は名前付きパラメータです。
  • オプションの追加パラメータをいくつでも追加して、ルートにヒットすることができます。

1
あなたは何をしようとしているのですか?感嘆符を知る必要がない場合は、知ってください'/path/:firstParam/*'。必要な場合は、実行してください'/path/:firstParam/:secondParam?/*'
Jonathan Ong 2012

1
スプラットをオプションにすることを検討しています-最初に示した例は一致しません/path/foo(オプションのスプラットが必要になる前の私のルートは元々どのようでしたか)。さらに、2番目の例では、スプラットを追加すると、オプションの2/path/foo番目のパラメーターが実際に無効になります-2番目のパターンと一致しません(/path/foo/barそのことについても...)-エクスプレスルーターのより厄介な部分の1つです。
ジェシー

1
個人的に私はちょうどのために行くだろう/path/:firstParam/path/:firstParam/:secondParam/共有コントローラを持つ2つの別々のルータとして。URLを混乱させる必要はありません
Jonathan Ong 2012

持ってn、私はそうのparamsの数に制限を持つ、それは任意の番号にすることができ、1-3のparamsへのルーティングではないよ確かに、私は10個のエンドポイントを作成することができますオプション(されていません-エンドポイントをアプリの設計のために必要ですしかし、エクスプレスでその作業を行うことは、ルートで行うよりも優れているわけではありません)。正規表現ルートを使用して問題(現在行っていること)を解決できますが、読み取り可能なオプションがあることを望んでいました。
ジェシー

開発者が名前付きのオプションのパラメータに単に括弧を使用することを考えていなかったことは驚くべきことです。すなわち/path/:param(/:otherOptionalParam)
r3wt 2017年

回答:


111

これは、エクスプレス4の/ pathおよび/ path / fooで機能し、*前に注意してください?

router.get('/path/:id*?', function(req, res, next) {
    res.render('page', { title: req.params.id });
});

43
これは機能しますが/path/foo/bar/bazzlereq.params.idにアクセスするとfooreq.params[0]に等しくなり/bar/bazzle、に等しくなり、一部の人がつまずく可能性があることに注意してください。よりクリーンな解決策は、パスをとして定義することです。これは、/path/*?Express 4ではに設定さreq.params[0]れますfoo/bar/bazzle。これは、おそらく探しているものに近いものです。
ジェシー2015年

オプションのパラメータをURLエンコードすることをお勧めします-スラッシュ付きのものを許可すると、app.get( 'path /:required1 /:required2 /:optional?*'のようなパスを追加したい場合に競合が発生することを意味します、ハンドラー)
ヨルダン

@Jesse最後の部分を必要にする方法はありますか?たとえば、私はマッチさせたい/path/foo/barが、ありません /path/foo。試しました'/path/:id/*が、*空の文字列にも一致するようです。
フランクリンユー

73

私は同じ問題を抱えてそれを解決しました。これは私が使用したものです:

app.get('path/:required/:optional?*', ...)

これがために働く必要がありpath/meowpath/meow/voofpath/meow/voof/moo/etc...

との/?を削除すると*、最後/もオプションになりますが、:optional?オプションのままです。


涼しい!私はこれをテストしたばかりで(Express 3.0.0では、2.xではテストしていません)、動作します。これは私の正規表現ハックよりも間違いなくクリーンです。
ジェシー

5
これらの事前定義されたキーワードについてもっと読むことができる場所を知っていますか?
ヤノス2014

8
Express 4.0xでは、これは機能しなくなったようです
regretoverflow 2015年

2
@chrisはエクスプレス4でこれに答えました-それが最新なので、私は受け入れられた答えを彼に移しました。
ジェシー

これを使用して奇妙なエラーが発生しました。ゼロが含まれている数値の場合、expressはそれを切り捨てます。たとえば、/:id(id = 904、req.params.id = 9、およびreq.params.0 = 04)(expressは、何らかの理由でこの残りをここにダンプします)。クリスの答えはこれを修正します
emiidee 2015

17

これはあなたが求めていることをしますか?

app.all('/path/:namedParam/:optionalParam?',function(req,res,next){
  if(!req.params.optionalParam){
    // do something when there is no optionalParam
  } else {
    // do something with optionalParam
  }
});

Expressのルーティングの詳細については、http//expressjs.com/guide/routing.htmlをご覧ください。


2
この解決策は一致しますが、一致し/path/foo/barません/path/foo/bar/baz-私がしていることに必要な*スプラット一致.+-私は間違いなくrtfmを持っていますが、それについて言及していないようですので、おそらくそれは不可能です...
Jesse

3

これが私がこの問題を解決している現在の方法です。expressがオプションの名前付きparamを使用して任意の数のスプラットパラメータをサポートしているようには見えません。

app.all(/\/path\/([^\/]+)\/?(.+)?/,function(req,res,next){
  // Note: this is all hacked together because express does not appear to support optional splats.
  var params = req.params[1] ? [req.params[1]] : [],
      name = req.params[0];
  if(!params.length){
    // do something when there is no splat
  } else {
    // do something with splat
  }
});

読みやすさと一貫性のために、この名前付きparamsを使用したいと思います。これを可能にする別の回答が表面化した場合は、それを受け入れます。


2

あなたがこのURLを持っているとしましょう: /api/readFile/c:/a/a.txt

あなたがしたい場合はreq.params.pathしますc:

'/api/readFile/:path*

あなたがしたい場合はreq.params.pathしますc:/a/a.txt

'/api/readFile/:path([^/]*)'

0

オプションを使用した上記のソリューションは、Express 4では機能しません。検索パターンを使用していくつかの方法を試しましたが、どちらも機能しませんでした。そして、私はこのメソッドを見つけ、無制限のネストされたパス、http://expressjs.com/api.html#routerに対して起動されたようです

// this will only be invoked if the path starts with /bar from the mount point
router.use('/bar', function(req, res, next) {
  // ... maybe some additional /bar logging ...

  // to get the url after bar, you can try
  var filepath = req.originalUrl.replace(req.baseUrl, "");

  next();
});

すべての/ bar、/ bar / z、/ bar / a / b / cなどに一致します。その後、パラメータが入力されていないため、req.originalUrlを読み取ることができます。baseUrlとoriginalUrlを比較して、残りのパスを取得してみてください。


0

この問題を回避するには、URLとに末尾のスラッシュを追加するミドルウェアを組み合わせて使用​​します。ミドルウェアは、の後にrouter.get('/bar/*?', ...すべてを取得し、それだけの場合は/bar/戻ります。訪問者が要求した場合、ミドルウェアは要求にスラッシュを追加し、要求をに変換します。undefined/bar//barexpress-slash/bar/

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