首页 > 解决方案 > 使 req 对象可用于每个视图文件

问题描述

我有一个使用 Pug 视图的 Node Express Web 项目。

通过使用Response.locals对象,我可以使 ExpressRequest对象(req在我的代码中)可用于每个 pug 文件:

const app = require("express")();
app.use((req, res, next) => {
    res.locals.req = req;
    next();
});

使用这种方法有什么副作用吗?有什么缺点?

我得到的便利是任何视图文件都可以访问Request对象的所有属性,例如查询字符串等,而不必使用教科书方法显式传递它们,例如:

app.get("/xx", (req, res) => {
    res.render("xx", { query: req.query });
});

标签: node.jsexpress

解决方案


使用这个有什么副作用吗?有什么缺点?它会占用大量内存吗?

使用带有 express 的模板引擎没有副作用。其实你可以res.render改用。


我得到的方便是视图文件可以访问查询字符串,

如果我们知道req.query我们需要什么,那么问题是如何为每条路线解析模板?

我们需要将解决方案分成两部分。

  • 第一部分 - 生殖器请求句柄。

尽管响应是动态的,但请求解析是已知的。假设我们在req对象上有一个附加参数,req.template并且我们req.query也可以使用。

下面的函数将渲染req.queryreq.template发送响应。

function pugTemplateHandler(req, res) {
   const compiledFunction = pug.compileFile(req.template);
   res.send(compiledFunction(req.query));
}

我们在这里不关心MethodRoutes。我们希望req在调用它之前设置它。

  • 第二部分——根据路由和方法解析模板文件

上面我们承诺会pugTemplateHandler为此req做好准备。我们可以使用中间件在对象上设置我们需要的成员req

app.get('...', (req, res, next) => {
    req.template = 'PUG_TEAMPLATE_PAT';   // resolve template
    // req.query = { ... };               // add or overwrite use params
    next();
}, pugTemplateHandler);                   // pass modified req

app.post('...', (req, res, next) => { ... }, pugTemplateHandler);
app.put('...', (req, res, next) => { ... }, pugTemplateHandler);
app.del('...', (req, res, next) => { ... }, pugTemplateHandler);

因为我们知道 HTTP MethodRoute解析模板很容易。这里的模板很可能是静态字符串。

该解决方案是可扩展的,并且尊重关注点分离的思想。


推荐阅读