255

私はexpressとnode.jsに少し慣れていないので、app.useとapp.getの違いを理解できません。どちらも使って情報を送れるようです。例えば:

app.use('/',function(req, res,next) {
    res.send('Hello');
    next();
});

これと同じようです:

app.get('/', function (req,res) {
   res.send('Hello');
});
4

7 に答える 7

259

app.use()ミドルウェアをアプリケーションにバインドすることを目的としています。これpathは「マウント」または「プレフィックス」パスであり、ミドルウェアが要求されたパスで始まるパスにのみ適用されるようにミドルウェアを制限します。別のアプリケーションを埋め込むためにも使用できます。

// subapp.js
var express = require('express');
var app = modules.exports = express();
// ...
// server.js
var express = require('express');
var app = express();

app.use('/subapp', require('./subapp'));

// ...

/マウント」パスとして指定することにより、は、app.use()で始まるすべて/のパスに応答します。これらはすべて、使用されるHTTP動詞に関係なく次のようになります。

  • GET /
  • PUT /foo
  • POST /foo/bar

app.get()一方、ExpressのアプリケーションルーティングGETの一部であり、 HTTP動詞で要求されたときに特定のルートを照合して処理することを目的としています。

  • GET /

そして、あなたの例の同等のルーティングapp.use()は実際には次のようになります。

app.all(/^\/.*/, function (req, res) {
    res.send('Hello');
});

更新:違いをよりよく示すことを試みています。

を含むルーティングメソッドは、app.get()リクエストへの応答をより正確に調整するのに役立つ便利なメソッドです。また、パラメータやなどの機能のサポートも追加されていますnext('route')

それぞれの中にapp.get()はへの呼び出しがapp.use()あるので、これらすべてをapp.use()直接行うことができます。ただし、これを行うには、多くの場合(おそらく不必要に)さまざまな量の定型コードを再実装する必要があります。

例:

  • 単純な静的ルートの場合:

    app.get('/', function (req, res) {
      // ...
    });
    

    対。

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
    
  • 同じルートに複数のハンドラーがある場合:

    app.get('/', authorize('ADMIN'), function (req, res) {
      // ...
    });
    

    対。

    const authorizeAdmin = authorize('ADMIN');
    
    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      authorizeAdmin(req, res, function (err) {
        if (err) return next(err);
    
        // ...
      });
    });
    
  • パラメータ付き:

    app.get('/item/:id', function (req, res) {
      let id = req.params.id;
      // ...
    });
    

    対。

    const pathToRegExp = require('path-to-regexp');
    
    function prepareParams(matches, pathKeys, previousParams) {
      var params = previousParams || {};
    
      // TODO: support repeating keys...
      matches.slice(1).forEach(function (segment, index) {
        let { name } = pathKeys[index];
        params[name] = segment;
      });
    
      return params;
    }
    
    const itemIdKeys = [];
    const itemIdPattern = pathToRegExp('/item/:id', itemIdKeys);
    
    app.use('/', function (req, res, next) {
      if (req.method !== 'GET') return next();
    
      var urlMatch = itemIdPattern.exec(req.url);
      if (!urlMatch) return next();
    
      if (itemIdKeys && itemIdKeys.length)
        req.params = prepareParams(urlMatch, itemIdKeys, req.params);
    
      let id = req.params.id;
      // ...
    });
    

注:Expressによるこれらの機能の実装は、、、、およびRouterLayerRoute含まれています。

于 2013-03-24T17:44:48.657 に答える
56

app.useExpressが依存するミドルウェアフレームワークであるConnectの「下位レベル」の方法です。

これが私のガイドラインです:

  • app.getGETメソッドを公開する場合に使用します。
  • ミドルウェア(Expressで設定したルートに到着する前のHTTPリクエストのハンドラー)を追加する場合、またはルートをモジュール化する(たとえば、一連のルートを公開する)場合に使用app.useします他のWebアプリケーションが使用できるnpmモジュールから)。
于 2013-03-24T17:45:11.310 に答える
53

単にapp.useは「すべてのリクエストでこれを実行する」を
意味しますapp.getは「指定されたURLに対してGETリクエストでこれを実行する」を意味します</p>

于 2016-11-16T09:47:47.017 に答える
32

app.getHTTPメソッドがに設定されている場合に呼び出されますがGETapp.useHTTPメソッドに関係なく呼び出されるため、エクスプレスパッケージがアクセスできる他のすべてのRESTfulタイプの上にあるレイヤーを定義します。

于 2013-03-24T17:38:47.940 に答える
28

app.use&の違いapp.get

app.use→通常、アプリケーションにミドルウェアを導入するために使用され、すべてのタイプのHTTPリクエストを処理できます。

app.get→GETHTTPリクエストの処理専用です。

app.useさて、 &の間に混乱がありapp.allます。間違いなく、それらに共通することが1つあります。それは、両方がすべての種類のHTTP要求を処理できるということです。ただし、ミドルウェアにはapp.useを使用し、ルート処理にはapp.allを使用することを推奨するいくつかの違いがあります。

  1. app.use()→コールバックは1回だけです。
    app.all()→複数のコールバックがかかる場合があります。

  2. app.use()URLが指定されたパスで始まるかどうかのみが表示されます。
    ただし、app.all()完全なパスと一致します。

例えば、

app.use( "/book" , middleware);
// will match /book
// will match /book/author
// will match /book/subject

app.all( "/book" , handler);
// will match /book
// won't match /book/author   
// won't match /book/subject    

app.all( "/book/*" , handler);
// won't match /book        
// will match /book/author
// will match /book/subject
  1. next()内でapp.use()呼び出すと、次のミドルウェアまたは任意のルートハンドラーがnext()呼び出されますが、内でapp.all()呼び出すと、次のルートハンドラー(app.all()などapp.get/post/put...)のみが呼び出されます。後にミドルウェアがある場合はスキップされます。したがって、すべてのミドルウェアを常にルートハンドラーの上に配置することをお勧めします。
于 2018-05-29T11:01:30.683 に答える
7

上記の説明に加えて、私が経験すること:

app.use('/book', handler);  

URLとして「/book」で始まるすべてのリクエストに一致します。したがって、「/ book/1」または「/book/2」にも一致します

app.get('/book')  

完全一致のGETリクエストのみに一致します。'/ book/1'や'/book/2'のようなURLは処理しません

したがって、すべてのルートを処理するグローバルハンドラーが必要な場合は、それapp.use('/')がオプションです。app.get('/')ルートURLのみを処理します。

于 2019-10-11T14:31:35.230 に答える
2

これまでに見つけた主な違いは3つあります。3つ目はそれほど明白ではなく、興味深いと思うかもしれません。違いはエクスプレスでも同じですrouter。つまりrouter.use()、およびrouter.get()/または他のpost、、、putなどのallメソッドにも同じ違いがあります。

1

  • app.use(path, callback)HTTPリクエストに応答します。
  • app.get(path, callback)GETHTTPリクエストにのみ応答します。同様にpost、、、putなどは対応するリクエストに応答します。app.all()HTTPリクエストに応答するのでapp.use()app.all()この部分でも同じです。

2

  • app.use(path, callback)リクエストパスのプレフィックスと一致し、リクエストパスのプレフィックスがパスパラメータと一致した場合に応答します。パスパラメータが、の場合など、、、など"/"に一致します。"/""/about""/users/123"
  • app.get(path, callback)ここでgetはパス全体に一致します。他のHTTPリクエストとapp.all()。たとえば、パスパラメータが"/"、の場合、一致するのは。だけ"/"です。

3

next('route') のミドルウェア/コールバック関数では機能しませんapp.use()app.get()app.all()および他のHTTPリクエストの他の同様の機能でのみ機能します。

エクスプレスドキュメントによると:

next('route')は、app.METHOD()またはrouter.METHOD()関数を使用してロードされたミドルウェア関数でのみ機能します。

METHODは、ミドルウェア関数が小文字で処理する要求(GET、PUT、POSTなど)のHTTPメソッドです。

ここから、、、などの代わりにキーワードMETHODを使用します。getしかし、 何ですか?!postall
next('route')

どれどれ。

next('route')

表示されるか、app.use()いくつapp.METHOD()かのコールバック/ミドルウェア関数を受け取ることができます。

エクスプレスドキュメントから:

ミドルウェア関数は、要求オブジェクト(req)、応答オブジェクト(res)、およびアプリケーションの要求/応答サイクルの次のミドルウェア関数にアクセスできる関数です。次のミドルウェア関数は通常、nextという名前の変数で示されます。

現在のミドルウェア関数が要求/応答サイクルを終了しない場合は、next()を呼び出して、次のミドルウェア関数に制御を渡す必要があります。それ以外の場合、リクエストはハングしたままになります。

したがって、各ミドルウェア関数は次のミドルウェア関数を呼び出すか、応答を終了する必要があることがわかります。そして、これはとについても同じapp.use()ですapp.METHOD()

ただし、状況によっては、現在のルートの次のコールバック関数をすべてスキップしたいが、今すぐ応答を終了したくない場合があります。多分一致する必要がある他のルートがあるからです。したがって、応答を終了せずに現在のルートのすべてのコールバック関数をスキップするには、を実行できますnext('route')。現在のルートのすべてのコールバック関数をスキップし、次のルートに一致するように検索します。

(エクスプレスドキュメントから):

app.get('/user/:id', function (req, res, next) {
  // if the user ID is 0, skip to the next route
  if (req.params.id === '0') next('route')
  // otherwise pass the control to the next middleware function in this stack
  else next()
}, function (req, res, next) {
  // send a regular response
  res.send('regular')
})

// handler for the /user/:id path, which sends a special response
app.get('/user/:id', function (req, res, next) {
  res.send('special')
})

ここで、特定の条件(req.params.id === '0')で次のコールバック関数をスキップしたいが、一致する同じパスパラメータの別のルートがあり、そのルートが特別な応答を送信するため、応答を終了したくない場合を参照してください。(ええ、同じパスパラメータを同じMETHOD数回使用することは有効です。そのような場合、応答が終了するまですべてのルートが一致します)。したがって、このような場合、を実行するnext('route')と、現在のルートのすべてのコールバック関数がスキップされます。ここで、条件が満たされない場合は、次のコールバック関数を呼び出します。

このnext('route')動作は、関数でのみ可能app.METHOD()です。

エクスプレスドキュメントからのリコール:

next('route')は、app.METHOD()またはrouter.METHOD()関数を使用してロードされたミドルウェア関数でのみ機能します。

では、現在のルートのすべてのコールバック関数をスキップすることはできないためapp.use()、ここでは注意が必要です。app.use()どのような状況でもスキップする必要のないミドルウェア機能のみを使用する必要があります。応答を終了するか、すべてのコールバック関数を最初から最後までトラバースする必要があるため、それらをスキップすることはできません。

詳細については、こちらをご覧ください。

于 2020-10-21T17:01:30.783 に答える