我是表达和node.js的新手,我无法弄清楚app.use和app.get之间的区别。看起来你可以使用它们来发送信息。例如:
app.use('/',function(req, res,next) {
res.send('Hello');
next();
});
似乎与此相同:
app.get('/', function (req,res) {
res.send('Hello');
});
答案 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')
)是便捷方法,可帮助您更准确地将响应与请求对齐。他们还添加了对parameters和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();
// ...
});
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
, andRoute
。
答案 1 :(得分:43)
app.use
是来自Connect的“低级”方法,Connect是Express所依赖的中间件框架。
这是我的指南:
app.get
。app.use
例如,从npm模块公开一组其他Web应用程序可以使用的路由。答案 2 :(得分:37)
简单地
app.use表示“在所有请求中运行此”
app.get表示“对GET请求运行此命令,对于给定的URL”
答案 3 :(得分:26)
答案 4 :(得分:11)
app.use
&amp;之间的差异app.get
:
app.use
→它通常用于在您的应用程序中引入中间件,并可以处理所有类型的HTTP请求。
app.get
→它仅用于处理GET HTTP请求。
现在,app.use
和{}之间存在混淆。 app.all
。毫无疑问,它们之间有一个共同点,即两者都可以处理所有类型的HTTP请求。
但是有些差异建议我们将app.use用于中间件和app.all进行路由处理。
app.use()
→只需一次回拨
app.all()
→可能需要多次回调。
app.use()
只会看到网址是否以指定路径开头
但是,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/author
next()
在app.use()
内调用将调用下一个中间件或任何路由处理程序,但next()
内app.all()
调用将调用下一个路由处理程序({{1} }},app.all()
等等。如果之后有任何中间件,则会跳过它。因此,建议将所有中间件始终放在路由处理程序之上。答案 5 :(得分:1)
到目前为止,我发现了3个主要区别。第三部分不是那么明显,您可能会发现它很有趣。差异对于快递router
是相同的。这意味着router.use()
和router.get()
或其他post
,put
,all
等方法也具有相同的区别。
1个
app.use(path, callback)
将响应任何HTTP请求。app.get(path, callback)
仅响应GET
HTTP请求。 post
,put
等将以相同的方式响应其相应的请求。 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代替get
,post
,all
等。
但是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。