Nodejs express多个路由最后render都需要同一个数据,怎么设计比较好?

Nodejs express多个路由最后render都需要同一个数据,怎么设计比较好?

比如查用户信息 一般的写法就是在每个路由都写查数据的逻辑最后render的时候给user对象,这样如果后期要改 比如 render的时候去掉user或是需要加另一个多个路由都需要的render的时候需要的对象,怎么设计这个逻辑比较有利于后期的改动?

3 回复

在使用 Node.js 和 Express 构建 Web 应用时,常常会遇到多个路由在渲染视图之前需要传递相同的数据。为了提高代码的可维护性和扩展性,可以将这部分公共逻辑提取出来,集中管理。以下是几种常见的设计方法:

方法一:中间件

你可以创建一个中间件函数,用于在路由处理函数执行后,但在响应发送前,添加需要共享的数据到 res.locals 对象中。res.locals 是一个局部变量对象,可以在所有模板引擎中访问。

const express = require('express');
const app = express();

// 中间件函数
function addUserToLocals(req, res, next) {
    // 假设你有一个获取用户信息的方法
    const user = getUserInfo();
    res.locals.user = user;
    next(); // 继续处理下一个中间件或路由
}

app.use(addUserToLocals);

// 路由示例
app.get('/home', (req, res) => {
    res.render('home', { title: 'Home Page' });
});

app.get('/profile', (req, res) => {
    res.render('profile', { title: 'Profile Page' });
});

在这个例子中,无论 /home 还是 /profile 被请求,addUserToLocals 中间件都会确保 user 数据被添加到 res.locals 中,并且可以在任何渲染的视图中访问。

方法二:路由处理器

另一种方法是在每个路由处理函数中调用一个通用的函数来获取并设置共享数据。虽然这种方法不如中间件灵活,但依然有效。

async function getUserData(req, res, next) {
    try {
        const user = await getUserInfo();
        res.locals.user = user;
        next();
    } catch (err) {
        next(err);
    }
}

app.get('/home', getUserData, (req, res) => {
    res.render('home', { title: 'Home Page' });
});

app.get('/profile', getUserData, (req, res) => {
    res.render('profile', { title: 'Profile Page' });
});

结论

使用中间件是一种更推荐的方法,因为它可以为多个路由提供一致的行为,并且易于管理和扩展。而使用通用函数作为路由处理器虽然简单,但可能会导致代码重复。根据你的具体需求选择最合适的方法。


模板内可读全局变量,你可以定义一个全局用的命名空间然后直接在模板里用。

为了使你的Node.js Express应用更加模块化和易于维护,可以将重复的渲染逻辑提取到中间件或自定义函数中。这不仅减少了代码重复,还能使未来的修改更加方便。

示例代码

  1. 创建一个辅助函数: 首先,你可以创建一个辅助函数来获取用户信息并准备渲染的数据。
// utils/userInfo.js
const getUserInfo = async (req, res, next) => {
    try {
        const user = await fetchUserInfo(req.params.userId); // 假设fetchUserInfo是一个获取用户信息的函数
        req.userInfo = { user, additionalData: 'some data' }; // 将用户信息附加到req对象
        next();
    } catch (err) {
        next(err);
    }
};
  1. 使用中间件在路由前调用辅助函数
const express = require('express');
const app = express();

// 引入辅助函数
const { getUserInfo } = require('./utils/userInfo');

app.get('/user/:userId', getUserInfo, (req, res) => {
    res.render('userProfile', req.userInfo);
});

app.get('/anotherRoute', getUserInfo, (req, res) => {
    res.render('anotherPage', req.userInfo);
});
  1. 处理错误: 如果你需要捕获任何可能发生的错误,可以在next函数中传递错误对象,并在Express应用中添加错误处理中间件。
app.use((err, req, res, next) => {
    console.error(err.stack);
    res.status(500).send('Something broke!');
});

解释

  • 辅助函数getUserInfo负责从数据库或其他源获取用户信息,并将其附加到请求对象req上。这使得你在多个路由中都能访问到相同的信息。
  • 中间件:通过在路由之前使用getUserInfo作为中间件,确保了每次进入特定路由时都会执行相同的逻辑来获取用户信息。
  • 渲染:在路由处理函数中,你可以直接使用req.userInfo进行渲染,从而减少重复代码。

这种方法提高了代码的可维护性,因为所有关于如何准备和渲染用户信息的逻辑都被集中管理在一个地方。如果未来需要更改用户信息的获取方式或增加其他全局数据,只需要修改辅助函数即可。

回到顶部