我对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');
});
我对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');
});
app.get在HTTP方法设置为GET时被调用,而app.use则不管HTTP方法是什么都被调用,因此它定义了一个层,该层位于快速包提供给你访问的所有其他RESTful类型之上。
App.use()用于将中间件绑定到应用程序。该路径是一个“挂载”或“前缀”路径,并限制中间件只能应用于以它开头的请求的任何路径。它甚至可以用来嵌入另一个应用程序:
// 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 / 把/ 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()完成所有这些。但是,这样做通常需要(可能是不必要的)重新实现各种数量的样板代码。
例子:
For simple, static routes: app.get('/', function (req, res) { // ... }); vs. app.use('/', function (req, res, next) { if (req.method !== 'GET' || req.url !== '/') return next(); // ... }); With multiple handlers for the same route: app.get('/', authorize('ADMIN'), function (req, res) { // ... }); vs. 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); // ... }); }); With parameters: app.get('/item/:id', function (req, res) { let id = req.params.id; // ... }); vs. 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对这些特性的实现包含在它的路由器、层和路由中。
app.use是Connect (Express所依赖的中间件框架)中的“低级”方法。
以下是我的指导原则:
如果你想公开一个GET方法,请使用app.get。 如果你想添加一些中间件(HTTP请求到达你在Express中设置的路由之前的处理程序),或者如果你想让你的路由模块化(例如,从npm模块中公开一组路由供其他web应用程序使用),请使用app.use。
app.use和app.get的区别:
app.use→它通常用于在应用程序中引入中间件,可以处理所有类型的HTTP请求。
app.get→仅用于处理GET HTTP请求。
现在,app.use和app.all之间有一个混淆。毫无疑问,它们有一个共同点,那就是它们都可以处理所有类型的HTTP请求。 但有一些区别,建议我们使用app.use作为中间件,而app.all用于路由处理。
app.use()→只需要一个回调。 app.all()→它可以接受多个回调。 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
在app.use()内部的Next()调用将调用下一个中间件或任何路由处理程序,但在app.all()内部的Next()调用将调用下一个路由处理程序(app.all(), app.get/post/put…只等)。如果后面有任何中间件,它将被跳过。因此,建议将所有中间件始终放在路由处理程序之上。
除了以上的解释,我所经历的:
app.use('/book', handler);
将匹配所有以“/book”开头的请求。所以它也匹配" /book/1 "或" /book/2 "
app.get('/book')
只匹配精确匹配的GET请求。它不会处理像'/book/1'或'/book/2'这样的url
所以,如果你想要一个全局处理程序来处理你所有的路由,那么app.use('/')是选项。app.get('/')将只处理根URL。
到目前为止,我发现有3个主要的区别。第三个不是很明显,你可能会觉得它很有趣。对于快速路由器,差异是相同的。这意味着router.use()和router.get()或其他post、put、all、etc方法也有相同的区别。 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参数匹配,则响应。例如,如果路径参数是“/”,那么它将匹配“/”,“/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是中间件函数请求的HTTP方法 句柄(如GET, PUT或POST)小写。
从这里开始,我们将使用关键字METHOD而不是get、post、all等。 但是下一步(“路线”)是什么?!
让我们来看看。
next()”)
我们看到,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')
})
See, here in a certain condition(req.params.id === '0') we want to skip the next callback function but also don't want to end the response because there is another route of the same path parameter which will be matched and that route will send a special response. (Yeah, it is valid to use the same path parameter for the same METHOD several times. In such cases, all the routes will be matched until the response ends). So in such cases, we run the next('route') and all the callback function of the current route is skipped. Here if the condition is not met then we call the next callback function.
这个next('route')行为只可能在app.METHOD()函数中出现。
从明确的文件中回顾:
next('route')只适用于通过app.METHOD()或router.METHOD()函数加载的中间件函数。
由于在app.use()中不可能跳过当前路由的所有回调函数,因此我们在这里应该小心。我们应该只使用app.use()中的中间件函数,这些函数在任何情况下都不需要跳过。因为我们要么必须结束响应,要么从头到尾遍历所有回调函数,所以我们根本不能跳过它们。
你可以访问这里了解更多信息
每次请求发送到服务器时,都会调用App.use。 唯一的事情是我们应该在处理get, put, post等请求之前调用它
app.use(middleware);
function middleware(req, res, next)
{
console.log("Came in middleware function without arrow");
next();
}
App.get只对给定路径的get请求被调用。
app.get('/myget', myget_function);
function myget_function(req, res)
{
console.log("Came in function myget");
res.send('Hello World! from myget');
}
post只在给定路径的post请求时被调用。
app.post('/mypost', mypost_function);
function mypost_function(req, res)
{
console.log("Came in function mypost");
res.send('Hello World! from mypost');
}