我有一个小小的困境,我正在尝试制作一个具有更改视图目录和
node.js
服务器布局的功能的网站:
app.use((req, res, next) => {
const segments = req.path.split('/');
const basePath = segments[1];
switch (basePath) {
case 'admin':
app.set('views', path.join(__dirname, 'views/admin'));
app.set('layout', path.join(__dirname, 'views/layouts/admin'));
break;
case 'user':
app.set('views', path.join(__dirname, 'views/worker'));
app.set('layout', path.join(__dirname, 'views/layouts/worker'));
break;
case 'guest':
app.set('views', path.join(__dirname, 'views/user'));
app.set('layout', path.join(__dirname, 'views/layouts/user'));
break;
default:
app.set('views', path.join(__dirname, 'views/def'));
app.set('layout', path.join(__dirname, 'views/layouts/def'));
break;
}
next();
});
我已经导入了我需要的所有模块,并且我正在做
app.use()
来满足需要的功能,这样做的问题是 app.set
全局设置视图目录和布局文件,这意味着它将导致问题当两个或多个用户同时访问不同的路由时。还有其他好方法吗?如果我是傻瓜,请叫我笨蛋,很高兴获得帮助。
我认为不断设置视图和布局目录是不必要的,甚至实际上是有问题的。正如您所说,这带来的问题多于它解决的问题,主要是因为您的具体问题:
views
和 layout
目录是为整个应用程序设置的。典型的方法是(在您的情况下)有 3 个不同的 Router
,每个处理 admin
、user
和 guest
的请求。
因此,您只需将视图和布局目录设置为
views
和 views/layouts
一次,并在各自的路线中处理不同类型的用户。
app.js
import adminRouter from '/path/to/adminFile.js';
import userRouter from '/path/to/userFile.js';
import guestRouter from '/path/to/guestFile.js';
// maybe also router for the default case, depending on how many subroutes there are
// import defRouter from '/path/to/defFile.js';
...
app.set('views', path.join(__dirname, 'views'));
app.set('layout', path.join(__dirname, 'views/layouts'))
...
app.use('/admin', adminRouter);
app.use('/user', userRouter);
app.use('/guest', guestRouter);
// app.use('*', defRouter);
// or just handle the default routes individually here
// app.get('*', (req, res) => {...});
adminFile.js
import express from 'express'
const adminRouter = express.Router();
adminRouter.get('/', (req, res) => {...});
...
export default adminRouter;
其他路由器也是如此。
然后,您可能实现了某种会话管理,因此您可以向仅应由特定类型的用户访问的路由添加更多路由处理程序。例如(使用
express-session
):
adminFile.js
import express from 'express'
const adminRouter = express.Router();
const isAdmin = (req, res, next) => {
if (req.session.user.type === "admin") {
next();
} else {
// redirect, send HTTP status code, do what you think would be appropiate
res.redirect('/');
// or
res.status(403).end("Forbidden access to admin route");
// or ...
}
}
adminRouter.get('/', isAdmin, (req, res) => {...});
...
export default adminRouter;
...
您可以为每个请求单独设置配置。
app.use((req, res, next) => {
const segments = req.path.split('/');
const basePath = segments[1];
switch (basePath) {
case 'admin':
res.locals.viewsDir = 'views/admin';
res.locals.layout = 'layouts/admin';
break;
...
}
next();
});
app.get('/:basePath/home', (req, res) => {
res.render('home', {
layout: res.locals.layout,
title: 'Home Page',
});
});