node.js express.js 中 app.use 和 app.get 的区别
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15601703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Difference between app.use and app.get in express.js
提问by Andre Vorobyov
I'm kind of new to express and node.js, and I can't figure out the difference between app.use and app.get. It seems like you can use both of them to send information. For example:
我对 express 和 node.js 有点陌生,我无法弄清楚 app.use 和 app.get 之间的区别。似乎您可以同时使用它们来发送信息。例如:
app.use('/',function(req, res,next) {
res.send('Hello');
next();
});
seems to be the same as this:
似乎与此相同:
app.get('/', function (req,res) {
res.send('Hello');
});
回答by Jonathan Lonowski
app.use()is intended for binding middlewareto your application. The pathis a "mount" or "prefix" path and limits the middleware to only apply to any paths requested that beginwith it. It can even be used to embed another application:
app.use()用于将中间件绑定到您的应用程序。这path是一个“ mount”或“ prefix”路径,并将中间件限制为仅适用于以它开头的任何请求路径。它甚至可以用来嵌入另一个应用程序:
// 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'));
// ...
By specifying /as a "mount" path, app.use()will respond to any path that starts with /, which are all of them and regardless of HTTP verb used:
通过指定/为“ mount”路径,app.use()将响应任何以 开头的路径,这些路径/都是它们,而不管使用的 HTTP 动词:
GET /PUT /fooPOST /foo/bar- etc.
GET /PUT /fooPOST /foo/bar- 等等。
app.get(), on the other hand, is part of Express' application routingand is intended for matching and handling a specific route when requested with the GETHTTP verb:
app.get()另一方面,是 Express应用程序路由的一部分,用于在使用GETHTTP 动词请求时匹配和处理特定路由:
GET /
GET /
And, the equivalent routing for your example of app.use()would actually be:
而且,您的示例的等效路由app.use()实际上是:
app.all(/^\/.*/, function (req, res) {
res.send('Hello');
});
(Update: Attempting to better demonstrate the differences.)
(更新:试图更好地展示差异。)
The routing methods, including app.get(), are convenience methods that help you align responses to requests more precisely. They also add in support for features like parametersand next('route').
路由方法,包括app.get(),是帮助您更精确地将响应与请求对齐的便捷方法。它们还添加了对参数和next('route').
Within each app.get()is a call to app.use(), so you can certainly do all of this with app.use()directly. But, doing so will often require (probably unnecessarily) reimplementing various amounts of boilerplate code.
每个内都有app.get()一个对 的调用app.use(),因此您当然可以app.use()直接使用所有这些操作。但是,这样做通常需要(可能是不必要的)重新实现不同数量的样板代码。
Examples:
例子:
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; // ... });
对于简单的静态路由:
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; // ... });
Note: Express' implementation of these features are contained in its
Router,Layer, andRoute.
注:快车实现这些功能都包含在它的
Router,Layer和Route。
回答by Matthew Ratzloff
app.useis the "lower level" method from Connect, the middleware framework that Express depends on.
app.use是来自 Connect 的“低级”方法,Express 所依赖的中间件框架。
Here's my guideline:
这是我的指导方针:
- Use
app.getif you want to expose a GET method. - Use
app.useif you want to add some middleware (a handler for the HTTP request before it arrives to the routes you've set up in Express), or if you'd like to make your routes modular (for example, expose a set of routes from an npm module that other web applications could use).
- 使用
app.get是否要公开一个GET方法。 - 使用
app.use,如果你想添加一些中间件(的处理程序HTTP请求它到达您在快速设置路线之前),或者如果你想使你的路由模块(例如,公开了一组路线来自其他 Web 应用程序可以使用的 npm 模块)。
回答by Dhyan Mohandas
Simply
app.use means “Run this on ALL requests”
app.get means “Run this on a GET request, for the given URL”
简单的 app.use 意味着“在所有请求上运行这个”
app.get 意味着“在一个给定的 URL 的 GET 请求上运行这个”
回答by MrLore
app.getis called when the HTTP methodis set to GET, whereas app.useis called regardless of the HTTP method, and therefore defines a layer which is on top of all the other RESTful types which the express packages gives you access to.
app.get当HTTP 方法设置为 时调用GET,而app.use不管 HTTP 方法如何调用,因此定义了一个层,该层位于 express 包允许您访问的所有其他 RESTful 类型之上。
回答by Ankit Kumar
Difference between app.use& app.get:
app.use&之间的区别app.get:
app.use→ It is generally used for introducing middlewares in your application and can handle all type of HTTP requests.
app.use→ 它通常用于在您的应用程序中引入中间件,可以处理所有类型的 HTTP 请求。
app.get→ It is only for handling GET HTTP requests.
app.get→ 仅用于处理 GET HTTP 请求。
Now, there is a confusion between app.use& app.all. No doubt, there is one thing common in them, that both can handle all kind of HTTP requests.
But there are some differences which recommend us to use app.use for middlewares and app.all for route handling.
现在,app.use&之间存在混淆app.all。毫无疑问,它们有一个共同点,它们都可以处理所有类型的 HTTP 请求。但是有一些差异建议我们将 app.use 用于中间件,将 app.all 用于路由处理。
app.use()→ It takes only one callback.app.all()→ It can take multiple callbacks.app.use()will only see whether url starts with specified path.
But,app.all()will match the complete path.
app.use()→ 只需要一个回调。app.all()→ 可能需要多次回调。app.use()只会查看 url 是否以指定路径开头。
但是,app.all()将匹配完整路径。
For example,
例如,
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
next()call inside theapp.use()will call either the next middleware or any route handler, butnext()call insideapp.all()will invoke the next route handler (app.all(),app.get/post/put...etc.) only. If there is any middleware after, it will be skipped. So, it is advisable to put all the middlewares always above the route handlers.
next()调用内app.use()将调用下一次执行中间件或路由处理,但next()里面调用app.all()将调用下一个路由处理器(app.all(),app.get/post/put...只等)。如果后面有中间件,则跳过。因此,建议将所有中间件始终放在路由处理程序之上。
回答by Atilla Baspinar
In addition to the above explanations, what I experience:
除了上面的解释,我的体会是:
app.use('/book', handler);
will match all requests beginning with'/book' as URL. so it also matches '/book/1' or '/book/2'
将匹配所有以'/book'开头的请求作为 URL。所以它也匹配 '/book/1' 或 '/book/2'
app.get('/book')
matches only GET request with exact match. It will not handle URLs like '/book/1' or '/book/2'
仅匹配具有完全匹配的GET 请求。它不会处理像“/book/1”或“/book/2”这样的 URL
So, if you want a global handler that handles all of your routes, then app.use('/')is the option. app.get('/')will handle only the root URL.
所以,如果你想要一个处理所有路由的全局处理程序,那么app.use('/')是选项。app.get('/')将只处理根 URL。

