Express JS 中间件的订购

Ordering of Express JS Middleware

我在摆弄 Express JS,正在使用 express-session。如果我不把 app.use(session()) 中间件放在首位,它就不起作用

app.use(session({
     name: 'server-session-cookie-id',
     secret: 'my express secret',
     saveUninitialized: true,
     resave: true
}));
app.use('/', routes);
app.set("view engine", "pug");
app.set("views", path.join(__dirname + "/views"));
app.use(flash());

如果 app.use(session()) 先写,它会说 req.session.someVariable 未定义。

谁能解释一下 Express 是如何调用 app.use 中间件的?

所有 Express 路由处理程序(无论是 app.use()app.get()app.post() 还是其他)都会按照它们注册的顺序检查路由匹配。此外,一旦路由发送请求并且不调用 next(),则不会检查其他路由是否与当前请求匹配。该请求的所有处理都将完成。

因此,您必须在任何想要使用该中间件结果的请求之前放置任何中间件。

有些人认为可能会检查所有 app.use() 处理程序是否匹配并可能在任何 app.get()app.post() 处理程序之前执行(如果它们与请求匹配)。事实并非如此。无论是哪种类型的处理程序,它们的注册顺序都有一个处理程序顺序。

It didn't work if I didn't put the app.use(session()) middleware first.

如果会话中间件不在想要使用会话的请求处理程序之前,那么当该请求处理程序运行时会话变量将不会被初始化,req.session 本身将是 undefined.

您必须将会话中间件放在任何想要使用会话变量的请求处理程序之前。

在测试环境中,作为纯hack,可以在开始时注入中间件,绕过初始化时的排序。

app.use(function test(req, res, next) { next() })
app._router.stack.splice(0, 0, app._router.stack.find(r => r.name === 'test'))