express.js中app.use和app.get之间的区别

时间:2013-03-24 17:32:04

标签: node.js 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');
});

7 个答案:

答案 0 :(得分:181)

app.use()用于将middleware绑定到您的应用程序。 path是“ mount ”或“前缀”路径,并将中间件限制为仅应用于 开始所请求的任何路径< / em> 用它。它甚至可以用于嵌入另一个应用程序:

// 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'));

// ...

通过将/指定为“ mount ”路径,app.use()将响应以/开头的所有路径,这些路径都是GET /使用的HTTP动词:

  • PUT /foo
  • POST /foo/bar
  • GET
另一方面,

app.get()是Express'application routing的一部分,用于在GET / HTTP动词请求时匹配和处理特定路由:

  • app.use()

而且,app.all(/^\/.*/, function (req, res) { res.send('Hello'); }); 示例的等效路由实际上是:

app.get()

更新:试图更好地展示差异。

路由方法(包括next('route'))是便捷方法,可帮助您更准确地将响应与请求对齐。他们还添加了对parametersapp.get()等功能的支持。

在每个app.use()内调用app.use(),因此您可以直接使用app.get('/', function (req, res) { // ... }); 完成所有这些操作。但是,这样做往往需要(可能不必要地)重新实现各种样板代码。

示例:

  • 对于简单的静态路由:

    app.use('/', function (req, res, next) {
      if (req.method !== 'GET' || req.url !== '/')
        return next();
    
      // ...
    });
    

    VS

    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);
    
        // ...
      });
    });
    

    VS

    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;
      // ...
    });
    

    VS

    {{1}}
  

注意:Express {这些功能的实现包含在其Router, Layer, and Route

答案 1 :(得分:43)

app.use是来自Connect的“低级”方法,Connect是Express所依赖的中间件框架。

这是我的指南:

  • 如果要公开GET方法,请使用app.get
  • 如果您想添加一些中间件(HTTP请求的处理程序到达您在Express中设置的路由之前),或者您希望使路由模块化,请使用app.use例如,从npm模块公开一组其他Web应用程序可以使用的路由。

答案 2 :(得分:37)

简单地 app.use表示“在所有请求中运行此”
app.get表示“对GET请求运行此命令,对于给定的URL”

答案 3 :(得分:26)

HTTP method设置为app.get时会调用

GET,而无论HTTP方法如何都会调用app.use,因此会定义一个位于快递包允许您访问的所有其他RESTful类型。

答案 4 :(得分:11)

app.use&amp;之间的差异app.get

app.use→它通常用于在您的应用程序中引入中间件,并可以处理所有类型的HTTP请求。

app.get→它仅用于处理GET HTTP请求。

现在,app.use和{}之间存在混淆。 app.all。毫无疑问,它们之间有一个共同点,即两者都可以处理所有类型的HTTP请求。 但是有些差异建议我们将app.use用于中间件和app.all进行路由处理。

  1. app.use()→只需一次回拨  app.all()→可能需要多次回调。

  2. app.use()只会看到网址是否以指定路径开头 但是,app.all()将匹配完整路径。

  3. 例如,

    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/author
    
    1. next()app.use()内调用将调用下一个中间件或任何路由处理程序,但next()app.all()调用将调用下一个路由处理程序({{1} }},app.all()等等。如果之后有任何中间件,则会跳过它。因此,建议将所有中间件始终放在路由处理程序之上。

答案 5 :(得分:1)

到目前为止,我发现了3个主要区别。第三部分不是那么明显,您可能会发现它很有趣。差异对于快递router是相同的。这意味着router.use()router.get()或其他postputall等方法也具有相同的区别。

1个

  • app.use(path, callback)将响应任何HTTP请求。
  • app.get(path, callback)仅响应GET HTTP请求。 postput等将以相同的方式响应其相应的请求。 app.all()响应任何HTTP请求,因此app.use()app.all()在此部分相同。

2

  • app.use(path, callback)将与请求路径的前缀匹配,并在请求路径的任何前缀与path参数匹配时作出响应。例如,如果path参数为"/",则它将匹配"/""/about""/users/123"等。
  • app.get(path, callback)这里的get将匹配整个路径。其他HTTP请求和app.all()相同。例如,如果path参数为"/",则它将仅匹配"/"

3

next('route') 不能使用app.use()的中间件/回调功能。它仅适用于app.get()app.all()和其他HTTP请求的其他类似功能。

根据快递文档

next('route')仅在使用app.METHOD()或router.METHOD()函数加载的中间件函数中起作用。

METHOD是中间件功能的请求的HTTP方法 小写的句柄(例如GET,PUT或POST)。

从这里开始,我们将使用关键字METHOD代替getpostall等。
但是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()中的中间件函数,无论如何都不要跳过它们。因为我们要么必须结束响应,要么必须从头到尾遍历所有回调函数,所以我们根本无法跳过它们。

您可以访问here以获得更多信息

答案 6 :(得分:0)

除了上面的解释之外,我的经验:

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

将匹配所有“ / book”作为URL的请求。因此它也匹配'/ book / 1'或'/ book / 2'

app.get('/book')  

仅匹配具有完全匹配的GET请求。它不会处理“ / book / 1”或“ / book / 2”之类的URL

因此,如果要使用全局处理程序来处理所有路由,则可以选择app.use('/')app.get('/')将仅处理根URL。