在Express js中,app.use()、app.get()、router.get()和router.use()有什么区别?

5

我仍然不知道这些端点的区别,它们都是路由,但我不知道何时或在哪里应该使用它?在什么情况下?

app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method)
  next()
});
app.get('/user/:id', function (req, res, next) {
  res.send('USER')
});

router.get('/user/:id', function (req, res, next) {
  res.send('USER')
});

router.use('/user/:id', function (req, res, next) {
  res.send('USER')
});

我希望你们能帮我解决这个问题。
3个回答

2
默认情况下,.use().get() 有两个主要区别。
  1. .get() 仅匹配 GET 请求,而 .use() 将匹配任何类型的请求(POST、PUT、GET 等)。
  2. 如果您向 .use() 提供路径,则其匹配更加自由,并且如果路径“以”您传递给 .use() 的路径开头,则会进行匹配。这样做是为了让您设置一个中间件处理程序,该处理程序将针对广泛的 URL 集触发,而不仅仅是单个 URL。 .get() 更常用于受限制的 URL,例如特定的 URL。
app.get() 几乎与 router.get() 相同。 app 对象是一个路由器,还具有其他一些属性和方法。因此,来自路由器对象的大多数方法也在 app 对象上,但反之则不然。
出于各种原因,您可能会使用路由器而不是应用程序对象:
  1. 代码模块化。一个模块创建自己的路由器,在其上设置一堆路由,然后导出单个路由器,调用者可以将其添加到当前应用程序中。
  2. 您有一堆具有相同前缀的路由,并且发现为该常见前缀设置路由器并仅在该路由器上放置路由而无需在每个路由中指定前缀更清晰。
  3. 创建一组共享相同中间件处理的路由,但应用程序中的其他路由不共享该中间件处理。在这种情况下,您创建路由器,在其上放置一些中间件,然后定义该路由器上的路由。中间件仅对路由到该路由器的路由触发。

一些例子:

// matches /hello and /hello/hi and /hello/goodbye for GET, POST or PUT
app.use('/hello', ...);

// matches only a GET request for /hello
app.get('/hello', ...);

使用路由器帮助实现模块化的示例。
一个具有一些已定义路由的模块:
// some_routes.js
const router = require('express').Router();

router.use(someMiddlewareForWholeRouter);

router.get('/hello', ...);
router.get('/goodbye', ...);
router.get('/callme', ...);

module.exports = router;

在您的应用程序中使用该模块:
// app.js
const some_routes = require('./some_routes.js');

// hook up all routes from some_routes with the path prefix of /greeting
app.use('/greetings', some_routes);

0

.use() 和 .get() 的区别在于 .use() 会监听任何类型的请求,而 .get() 只会监听 GET 请求,就像 .post()、.put() 等一样。

对于路由器,您可以将其视为子路由。

例如,您可以这样做。

router.get('/:id', (req, res, next) => {res.send('user')})
router.post('/', (req, res, next) => {/* some create user logic */})

app.use('/user', router) // if you do this routers will match '/user/:id' and '/user' path

当然,您可以在同一个应用程序中拥有多个路由器。因此,您的代码可以更加结构化。


-1
简要来说,对于这些对象:
Express应用程序可以独立路由,您只能在整个代码库中拥有一个应用程序,因此如果需要将多个路由模块化而无需传递应用程序引用,则可以拥有多个路由器并将它们导入到根应用程序中。
路由器是专用于路由的工具,您可以拥有多个路由器,并将其连接到Express应用程序上。
现在对于这些方法: use() 是基本方法的包装器,您可以在几个基本端点之间指定常见资源(如中间件),而 get() 用于指定端点,覆盖任何先前在其use()包装器中指定的路由。

Bergi的建议可能需要进一步扩展。我认为他们想表达的是,当引用材料(使用引用设备>)时,它必须来自某个地方 - 文档、维基、文章、演讲、电视节目等。这是引用块的语义含义,尽管有时它被用作一般的突出显示或分隔块。我已经删除了引用设备,以显示该文本是您的声音,而不是其他人的声音。 - halfer
啊哈,谢谢,我明白了。你说得对,我之前是用它来加亮。那现在我怎么能够突出想要凸显的部分呢? - whizboy
Markdown(至少在Stack Overflow上实现的)不提供突出框。也许可以使用“注意:”前缀。整个段落使用斜体可能有效,但可能会看起来过度格式化。 - halfer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接