【问题标题】:Sharing Server Side data to a JS file将服务器端数据共享到 JS 文件
【发布时间】:2019-02-28 05:22:55
【问题描述】:

我创建了一个简单的博客站点,其中包含帖子、用户和 cmets。 我正在使用带有 EJS 视图的 MongoDB、NodeJS 和 Express。 我在尝试创建 cmets 部分时遇到了问题。 我想使用带有 Ajax 请求的 JQuery 来制作 cmets 部分 所以当用户发表评论或编辑时页面不会刷新。

为了获取每个帖子的 cmets,我构建了一个如下所示的 api 路由 - www.domain.com/api/messages/:post_id 此 url 返回包含该帖子的 cmets 的 JSON。 我不想暴露关于评论作者的“风险”数据,所以我用 Mongo 查询填充了结果。

现在解决问题 - 我想为每个评论添加编辑和删除按钮,这些按钮当然只显示给管理员和作者。 当我使用 EJS 时,它很简单——我写了这样的东西——

<% if (user !== null&& (JSON.stringify(user._id) === JSON.stringify(comments[i].author._id) 
|| user.is_admin === true)) { %> 
put the buttons here...

问题是,当我在我的主脚本文件上使用 JQuery 时,我无法访问用户(这是从后端 Nodejs 发送的对象)。 我不确定我是否应该从 EJS 将这个对象“发送”到我的 js 文件中,我认为这不安全,也不是正确的方式。

我也不能保留几行前引用的 EJS 代码,因为当 EJS 文件加载时,该页面上没有 cmets(XHR 请求获取它们,而 JQuery 将它们放在页面上)。 所以我真的不知道如何继续。

编辑 - 我想我有一个解决方案:也许我应该在 EJS 文件上创建一个 ID 数组,其中包含需要这些按钮的 cmets,然后我会以某种方式将该数组发送到 JS 文件?

谢谢!

【问题讨论】:

  • 是的,您是对的,因为有人可以通过 user.is_admin = true 将用户对象从 ejs 发送到客户端代码的不安全方式,所以您是对的。所以你可以做的是有一个包含ejs代码的隐藏div,并在你的cmets完成加载时显示这个div。
  • 谢谢!我不认为我理解您的解决方案,评论是通过 xhr 请求获取的,那么我应该在 ejs 文件中隐藏什么?加载时页面上没有 cmets
  • 我的意思是你可以隐藏你的按钮,直到 cmets 没有以 ejs 方式加载。

标签: javascript node.js mongodb express ejs


【解决方案1】:

将用户和所有 cmets 发送到主 EJS 文件。

app.get('/', function (req, res) {
    res.render('index', {
        comments: [{ ... }, { ... }, { ... }], 
        user: { ... }
    });
});

可以通过在主EJS 文件中包含文件夹partials 中的a EJS partial comment.ejs 来呈现cmets。

<% comments.forEach(function(comment){ %>
    <% include partials/comment %>
<% }) %>

partial 中呈现评论和按钮。该评论已通过包含。用户已经使用 EJS 主模板。

<div class="comment-container" data-commentid="comment._id">
    <p><% comment.content %></p>
    <% if (user !== null&& (JSON.stringify(user._id) === JSON.stringify(comment.author._id) || user.is_admin === true)) { %> 
        <button class="button_delete" data-commentid="<% comments_id %>">delete</button>
    <% } %>
</div>

然后在您的API 中创建一个route,例如 www.domain.com/api/messages/delete/:post_id。

app.get('/messages/delete/:post_id', function(req, res){
    // logged on user lives on the server
    // check if user may delete comments
    // delete comment
    // send result
    res.send(true);
});

当您单击button 时,使用jQuery 将该ID 从buttondata attribute 发送到server/api,然后我将识别已登录的用户。如果登录的用户被授权删除它并发回结果。如果一切正常,请使用jQuery 删除包含整个消息的 div。

$('.button_delete').click(function(){
    // retrieve id from data attribute here
    var commentId = $(this).data("commentid");

    $.get('www.domain.com/api/messages/delete/' + commentId, {}, function(result){
        if(result) {
            // delete comment container from html using commentId or refresh
        }
    });
});

【讨论】:

  • 谢谢!但我想你不明白我的问题,我需要知道什么时候显示删除按钮。如果您能阅读我的编辑,我认为这会让事情变得更清楚。
  • 我澄清了我的回答。无需使用 jQuery 来加载您的 cmets。使用部分渲染每个评论。
  • 非常感谢,这与我的想法完全不同,因为我认为,一旦您走 XHR 路线,最好将其用于获取和发布(删除) .感谢您提供非常全面的解决方案。
【解决方案2】:

所以我想我设法克服了这个问题,我会发布我所做的,希望它对将来的人有所帮助。

EJS 文件中,我分配了一个数组,该数组将保存当前用户发布的 cmets 的 ID(该用户由 nodejd 后端发送到 EJS 文件)。

然后,我将此数组复制到 EJS 文件中的脚本标记变量中,通过这样做,我现在可以从 main.js 文件访问它,并将删除/编辑按钮仅添加到 ID 为的 cmets在数组中。

<% var arr = []; %>
<% for(var i = 0; i < comments.length ; i++){ %>
 <% if (user !== null && (JSON.stringify(user._id) === JSON.stringify(comments[i].author._id) || user.is_admin === true)) { %>
 <% arr.push(comments[i].comment_id); %> <% } %>
 <% } %>
 <script> 
var exported_array = <%- JSON.stringify(arr) %>
 </script>

【讨论】:

    猜你喜欢
    • 2012-04-15
    • 2011-11-24
    • 2019-12-09
    • 1970-01-01
    • 2012-06-04
    • 2021-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多