Nodejs中app.use(app.router);究竟是什么意思
Nodejs中app.use(app.router);究竟是什么意思
网上这一些答案看的不是很懂
今天在用express-flash的时候
app.use(express.cookieParser('shopmall'));
app.use(express.session({ cookie: { maxAge: 60000 }}));
app.use(flash());
必须要放在app.use(app.router);的前面,不然的话会报错说没有req.flash这个方法
Node.js 中 app.use(app.router);
究竟是什么意思?
引言
在使用 Express 框架时,你可能会遇到类似以下的代码片段:
app.use(express.cookieParser('shopmall'));
app.use(express.session({ cookie: { maxAge: 60000 }}));
app.use(flash());
这些中间件必须放在 app.use(app.router);
的前面。那么,app.use(app.router);
到底是什么意思呢?本文将通过一些简单的解释和示例代码来解答这个问题。
解释
在早期版本的 Express(如 v2.x)中,app.use(app.router);
是一个重要的步骤,用于注册路由处理程序。简单来说,app.use(app.router);
告诉 Express 在所有静态文件中间件之后运行路由中间件。然而,在现代版本的 Express(如 v4.x 及以上),app.use(app.router);
已经被废弃了。Express 自动处理路由,无需显式调用 app.use(app.router);
。
示例代码
让我们看看一个简单的 Express 应用程序,它使用了一些常见的中间件:
const express = require('express');
const app = express();
// 使用 Cookie 解析器
app.use(express.cookieParser('shopmall'));
// 使用 Session 中间件
app.use(express.session({ cookie: { maxAge: 60000 }}));
// 使用 Flash 中间件
app.use(flash());
// 定义一个路由
app.get('/', (req, res) => {
req.flash('info', 'Hello, world!');
res.send('Hello, world!');
});
// 启动服务器
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
在这个例子中,我们不需要显式地调用 app.use(app.router);
,因为现代 Express 版本会自动处理路由。
为什么需要放在前面?
对于你的问题,关于为什么 app.use(express.session({ cookie: { maxAge: 60000 }}));
和 app.use(flash());
必须放在 app.use(app.router);
前面,这实际上是因为在旧版本的 Express 中,app.router
会在所有中间件之后运行。因此,如果把它们放在 app.use(app.router);
后面,可能会影响中间件的功能。而在现代版本中,由于 app.use(app.router);
已经被废弃,这个问题就不再存在了。
结论
总之,app.use(app.router);
在现代 Express 应用中已经不再必要,理解这一点可以帮助你更好地编写和维护你的 Express 应用。
app.router的用途这里讲的很详细了。
简单理解:里边会创建一个路由map,把类似app.get、app.post等的所有路由的url和callback做一个映射保存,当req.url命中路由时执行相应的回调。如果不显式调用app.use(app.router);
则会在第一条路由里边隐式调用。
这里边,调用app.use(app.router);
时会暂存req对象,当后面再定义路由时,
app.get('/foo', function(req, res, next) {});
这里的req应该用的是之前保存下来的,所以会出现没有req.flash的错误(没细看express源码,这是猜测的~)。
express 的中间件写法.
完整而言是
app.use(function (req, res, next){
//为了我们能够使用 req.flash
req.flash = req.flash || {};
next();
});
然后,接下来我就可以获取req.flash 的定义了…为什么要放在前面?? 因为程序是自上而下的运行啊…
app.use(app.router);
在较旧版本的 Express(例如 3.x 版本)中用于定义路由处理中间件的位置。这行代码告诉 Express 在所有中间件之后注册路由处理程序。
但在现代的 Express 版本(4.x 及以上)中,这行代码已经不再需要了。路由和中间件会自动被应用到所有请求上,无需显式调用 app.router
。
根据你的问题,app.use(app.router);
需要在 app.use(flash())
前面的原因是因为在较旧版本的 Express 中,中间件必须在路由之前被注册。flash()
中间件依赖于请求/响应对象上的某些属性,这些属性通常由其他中间件(如 cookieParser
和 session
)设置。
示例代码
假设你使用的是较旧版本的 Express(例如 3.x),可以这样写:
var express = require('express');
var app = express();
// 使用中间件
app.use(express.cookieParser('shopmall'));
app.use(express.session({ cookie: { maxAge: 60000 }}));
app.use(app.router); // 注意:这是在Express 3.x中的用法
// 定义路由
app.get('/', function(req, res) {
req.flash('info', 'Hello World!');
res.send('Hello World!');
});
// 启动服务器
app.listen(3000);
现代版本的替代方式
如果你使用的是现代版本的 Express(例如 4.x 或更高版本),你可以直接这样写:
var express = require('express');
var session = require('express-session');
var flash = require('connect-flash');
var app = express();
// 使用中间件
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.use(session({ cookie: { maxAge: 60000 } }));
app.use(flash());
// 定义路由
app.get('/', function(req, res) {
req.flash('info', 'Hello World!');
res.send('Hello World!');
});
// 启动服务器
app.listen(3000);
在这段代码中,我们不需要显式调用 app.router
,因为 Express 会自动处理所有中间件和路由。