app.all( '*')とapp.use( '/')の違い


回答:


119

ほとんどの場合、それらは同等に機能します。最大の違いは、ミドルウェアが適用される順序です。

  • app.all() アプリケーションのルーターに接続するため、app.routerミドルウェアに到達するたびに使用されます(すべてのメソッドルートを処理します... GET、POSTなど)。

注意:app.routerはExpress 4.xで非推奨になりました

  • app.use()アプリケーションのメインミドルウェアスタックにアタッチされるため、ミドルウェアで指定された順序で使用されます。たとえば、最初に配置すると、最初に実行されます。最後に(ルーターの後)置くと、通常はまったく実行されません。

通常、すべてのルートに対してグローバルに何かを実行したい場合は、app.use()がより良いオプションです。また、Express 0.4はおそらく暗黙のルーターをドロップするため、将来のバグの可能性が低くなります(つまり、技術的に使用する必要がないため、ミドルウェア内のルーターの位置が現在よりも重要になります)たった今)。


15
これはExpress 4.x以降にも適用されますか?app.routerが削除されました。
ラフリー、2014

1
で使用できますnext("route")app.all、では使用できませんapp.use
JozefMikušinec2017

@JozefMikusinecドキュメンテーションは、そうでないことを示唆しているようです... expressjs.com/en/guide/writing-middleware.html
musicin3d 2017

あなたのリンクはnext( 'route')について言及していませんが、私はAPIを見ました、あなたは正しいです。
ジョゼフミクシネック2017

2
@ musicin3dさらに調査したところ、このGitHubの問題が見つかりました。これにより、「next()とnext( 'route')はapp.useとの違いはありません」(引用)。彼らはドキュメントを変更する必要があります。
JozefMikušinec2017

87

app.useはコールバック関数を1つだけ取り、それはミドルウェア用です。ミドルウェアは通常、要求と応答を処理しません(技術的には可能)、入力データを処理し、キュー内の次のハンドラーに渡します。

app.use([path], function)

app.allは複数のコールバックを受け取り、ルーティングを目的としています。複数のコールバックを使用すると、リクエストをフィルタリングして応答を送信できます。それはexpress.jsのフィルターで説明されています

app.all(path, [callback...], callback)

app.useは、URLが指定されたパスで始まるかどうかのみを確認します

app.use( "/product" , mymiddleware);
// will match /product
// will match /product/cool
// will match /product/foo

app.allは完全なパスに一致します

app.all( "/product" , handler);
// will match /product
// won't match /product/cool   <-- important
// won't match /product/foo    <-- important

app.all( "/product/*" , handler);
// won't match /product        <-- Important
// will match /product/
// will match /product/cool
// will match /product/foo

17
少なくともv4では、app.useは「1つだけ」ではなく、1 つ以上のミドルウェア関数を受け取ります。
ジェスオースティン

2
app.useは、URLが指定されたパスで始まるかどうかを確認するだけです。app.allは完全パスと一致します。これが主な違いです。
meizilp 2016

@frogcjnいいえ、それは私の質問の*と/を無視するため、すべきではありません。
ostergaard

15
  • app.use:

    1. たとえば、ヘッダー、Cookie、セッションなどを構成するフロントコントローラーにミドルウェアを挿入します。
    2. app [http_method]の前に記述する必要があります。そうでない場合は実行されません。
    3. いくつかの呼び出しは書き込み順に処理されます
  • app.all:

    1. (app [http_method]など)は、ルートのコントローラーの構成に使用されます
    2. 「すべて」は、すべてのhttpメソッドに適用されることを意味します。
    3. いくつかの呼び出しは書き込み順に処理されます

次のexpressJsコードサンプルをご覧ください。

var express = require('express');
var app = express();

app.use(function frontControllerMiddlewareExecuted(req, res, next){
  console.log('(1) this frontControllerMiddlewareExecuted is executed');
  next();
});

app.all('*', function(req, res, next){
  console.log('(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next');
  next();
});

app.all('/hello', function(req, res, next){
  console.log('(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next');
  next();
});

app.use(function frontControllerMiddlewareNotExecuted(req, res, next){
  console.log('(4) this frontControllerMiddlewareNotExecuted is not executed');
  next();
});

app.get('/hello', function(req, res){
  console.log('(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response');
  res.send('Hello World');
});

app.listen(80);

ルート「/ hello」にアクセスしたときのログは次のとおりです。

(1) this frontControllerMiddlewareExecuted is executed
(2) route middleware for all method and path pattern "*", executed first and can do stuff before going next
(3) route middleware for all method and path pattern "/hello", executed second and can do stuff before going next
(5) route middleware for method GET and path patter "/hello", executed last and I do my stuff sending response

6
この例をExpress 4.xで逐語的に実行すると、実際には5つすべてが順番に実行されます。これは、これが書かれてからほぼ3年間でエクスプレスの変更が原因である可能性がありますが、私は明確にするためにこれを追加すると思っていました。
Nathan Wiebe 2017年

11

ではapp.use()、「マウント」のパスが剥離し、ミドルウェアの機能には表示されません。

app.use('/static', express.static(__dirname + '/public'));

(ミドルウェア機能を搭載がexpress.staticない場合)に呼び出されていないreq.urlこのプレフィックス(含まれている/static)、それが剥離された時点で関数が呼び出されたときに。

ではapp.all()、そのような動作はありません。


app.use( '/'、...)についてのみ明示的に質問します。
ostergaard 2013年

これは、2018年にも当てはまる質問に対する正解です!ミドルウェアはall()でもマウントできます...唯一の違いは、ミドルウェアの実行時にマウントパスが削除されることです。
Xatian

4

はい、app.all()特定のURIが任意のタイプの要求メソッド(POST、GET、PUT、またはDELETE)で要求されたときに呼び出されます

一方app.use()、使用する可能性のあるすべてのミドルウェアに使用され、パスプレフィックスにマウントされ、そのルートの下のURIが要求されるたびに呼び出されます。

これがapp.allapp.useのドキュメントです。


感謝しますが、app.allワイルドカードとapp.useルートパスを逃したと思います。例外として、app.allは一連のコールバックを受け取ることができ、app.useは1つしか受け取ることができません-そうですか?
ostergaard 2013年

1

上記すべての2つの違いは言及されていません。

最初の1つapp.allは、パスパラメータとして正規表現を受け入れます。app.use正規表現を受け入れません。

2つ目: app.all(path,handler)またはapp[method](path,handler)、ハンドラーpathすべての ものと同じである必要がありますpath。is、app [method] 'path is complete。

app.use(path,hanlder)、使用のパスが完全な場合、ハンダーのパスは「/」でなければなりません。使用のパスが完全なパスの開始である場合、ハンドラーのパスは完全なパスの残りの部分でなければなりません。

 app.use('/users', users);

  //users.js:  the handler will be called when matchs `/user/` path
      router.get('/', function(req, res, next) {
      res.send('respond with a resource');
    });
  // others.js: the handler will be called when matchs `/users/users` path
      router.get('/users', function(req, res, next) {
      res.send('respond with a resource');
    });

app.all('/users', users);

//others.js: the handler wil be called when matchs `/`path
router.get('/', function(req, res, next) {
     res.send('respond with a resource');
});
//users.js: the handler will be called when matchs `/users` path
router.get('/users', function(req, res, next) {
    res.send('respond with a resource');
 });

0

2つの主な違いがあり

ます。1.パターンマッチング(Palaniによる回答)
2. next(route)を使用してロードされたミドルウェアの関数本体内では機能しませんapp.use。これはドキュメントからのリンクで述べられています:

NOTE: next('route') will work only in middleware functions that were loaded by using the app.METHOD() or router.METHOD() functions.

リンク:http : //expressjs.com/en/guide/using-middleware.html

の効果はnext('route')、次の例で確認できます。

app.get('/',
(req,res,next)=>{console.log("1");
next(route); //The code here skips ALL the following middlewares
}
(req,res,next)=>{next();}, //skipped
(req,res,next)=>{next();}  //skipped
);

//Not skipped
app.get('/',function(req,res,next){console.log("2");next();});
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.