【问题标题】:passing user data to the client将用户数据传递给客户端
【发布时间】:2014-03-04 09:26:23
【问题描述】:

我正在使用 nodejs、express、mongoose 和 passport 进行身份验证。
我有一个名为 User 的猫鼬模型,它包含用户数据(大量数据)。
不,我想创建一个渲染 index.jade 的路由并在模板中设置用户数据。
我的路线是:

app.get('/something', function(req, res) {
    res.render('index', {
        user: req.user || {}
    });
});

我的模板:

doctype 5
html(lang="en")
    head
    body
        script(type='text/javascript')
            window.user = #{user};

我有以下两个问题:

  1. 我不希望客户端获得整个用户结构。我只需要几个属性,仅此而已。我从 Java 和 .NET 知道有术语“数据传输对象”表示一个对象,其目的是将数据传递给客户端。节点中的等价物是什么?仅向客户端传递相关数据的节点的最佳实践是什么?

  2. 客户端需要用户 ID 来识别用户。我不想传递 mongo 原始用户文档 _id。我能做些什么?我是否需要以某种方式对 id 进行编码?

【问题讨论】:

  • 如果您查看 mongoose findOne 文档,您可以看到该调用带有一个可选的第二个参数,该参数列出了您想要的字段。您可以在 LocalStrategy 中使用它来限制返回对象中的字段数。例如User.findOne({ username: username }, "username user_id", function (err, user) { ...
  • @jimoleary:这不是 mongoose 层来决定我需要哪些数据。这个数据选择只与表示层有关,我知道我将把数据传递给谁。
  • 谁没看懂问题给我-1?

标签: javascript node.js mongodb express mongoose


【解决方案1】:

当您执行res.render 时,除了您在模板中使用的变量之外,您实际上不会从变量发送任何内容到您的客户端,所以基本上如果您只想传递您的用户的用户名,您可以安全地执行(使用干燥改进):

render = function(page, req, res) {
   res.render(page, { user: req.user ? req.user : {} });
};

app.get('/something', function(req, res) { render('index', req, res); });
app.get('/pageA', function(req, res) { render('pageA', req, res); });
app.get('/pageB', function(req, res) { render('pageB', req, res); });

doctype 5
html(lang="en")
    head
    body
        script(type='text/javascript')
            | window.user = "#{user.username}";

如果你想要更复杂的用户对象,你总是可以这样做:

doctype 5
html(lang="en")
    head
    body
        script(type='text/javascript')
            | window.user = { username: "#{user.username}", email: "#{user.email}" };

基本上,这不会将您的 user 对象暴露给客户端,而只会暴露给您的节点查看器实例的渲染函数。

关于用户 ID,您可以使用任何其他唯一的用户属性作为用户名、电子邮件地址等。

【讨论】:

  • 所以你实际上是说没有像数据传输对象这样的东西,我的模板应该保存模型的客户端数据表示?
  • 您的user 对象永远不会到达您客户端的浏览器,该对象只会传输到您的jade 编译器。按照您在原始问题中所做的方式,您将公开整个 user 对象,但如果您指定对象的深层属性,则永远不会公开整个对象!
  • 我明白这一点。但这似乎有问题。如果我有 3 个不同的页面要向他们提供用户数据怎么办?然后我需要复制我的模板代码来构建用户对象。关于我关于用户ID的第二个问题,你知道如何对ID进行编码吗?
  • 您渲染的每个模板都需要来自用户的数据。您可以创建一个默认布局模板,然后您就不需要每次都复制您的脚本代码,但“res.render”将始终需要user 参数。 encode id 是什么意思?
  • 那你建议的解决方案不好。我不想在每个需要用户的翡翠模板中创建用户结构。请看我关于用户ID的第二个问题。
【解决方案2】:

您可以序列化对象以在客户端上使用

doctype 5
html(lang="en")
    head
    body
        script(type='text/javascript')
            window.user = !={JSON.stringify(user)};

你也可以在服务器上序列化

app.get('/something', function(req, res) {
    res.render('index', {
        user: JSON.stringify(req.user || {})
    });
});

只需在视图中分配它

script(type='text/javascript')
    window.user = =#{user};

【讨论】:

  • 不想暴露真实id怎么传用户id?
  • 你可以delete user._id,虽然我不确定这样做的含义。你在用猫鼬吗?如果是这样看看这个toObject 你可以使用schema.options.toObject.transform 来定义一个删除id 的方法,或者你可以重载toObject 本身。您还可以将一组选项传递给toObject,这将从您的文档doc.toObject({ hide: '_id' }); 中删除_id
  • 但我需要某种用户 ID,因为我想更改用户数据。我不想使用原始 ID,而是使用它生成的其他 ID。
  • 我不确定我是否理解。您的“用户”模型是否包含您自己生成的 id?
  • 我有 user._id 属性,但我不希望客户端知道真正的 _id。
猜你喜欢
  • 2017-04-02
  • 2016-01-10
  • 2019-03-16
  • 1970-01-01
  • 2019-04-15
  • 1970-01-01
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
相关资源
最近更新 更多