【问题标题】:Passing an object to client in node/express + ejs?在 node/express + ejs 中将对象传递给客户端?
【发布时间】:2012-06-24 11:35:31
【问题描述】:

我有一个非常大的对象,我需要将它传递给客户端脚本中的函数。我曾尝试使用 JSON.stringify,但在使用这种方法时遇到了一些问题——主要与性能有关。在ejs中可以做这样的事情吗?

app.get('/load', function(req, res) {
    var data = {
        layout:'interview/load',
        locals: {
            interview: '',
            data: someLargeObj
        }
    };
    res.render('load', data);
});

在我的客户端脚本中,我会将这个对象传递给这样的函数

<script type="text/javascript">
    load(<%- data %>); // load is a function in a client script
</script>

当我尝试这个时,我得到了任何一个

<script type="text/javascript">
    load();
</script>

<script type="text/javascript">
    load([Object object]);
</script>

【问题讨论】:

  • JSON.stringify 是唯一的方法。
  • @FlorianMargaine,你能告诉我为什么在客户端使用'JSON.stringify()'吗?因为节点会将数据作为对象的形式传递,而 stringify 只会将其转换为字符串,而不是我们需要一个对象,对吗?没有 JSON.stringify() 就不行
  • @Vishal-Lia — 您应该在 EJS 代码中使用JSON.stringify server-side,而不是在传递给浏览器的&lt;script&gt; 数据中使用客户端。
  • @Vishal-Lia 您找到问题的答案了吗?下面的答案都没有告诉我们为什么当数据作为实例中的对象传递时我们必须JSON.stringify。另外,为什么JSON.stringify应该做相反的事情时将其转换为对象?

标签: node.js express ejs


【解决方案1】:

在 Node.js 中:

res.render('mytemplate', {data: myobject});

在 EJS 中:

<script type='text/javascript'>
  var rows =<%-JSON.stringify(data)%>
</script>

安全提示:不要使用它来渲染带有用户提供数据的对象。像Little Bobby Tables 这样的人可能会包含一个子字符串,该子字符串会破坏 JSON 字符串并启动一个可执行标签或类似的东西。例如,在 Node.js 中,这看起来很无辜......

var data = {"color": client.favorite_color}

但如果用户输入以下颜色,可能会导致客户端提供的脚本在用户的浏览器中执行:

"titanium </script><script>alert('pwnd!')</script> oxide"

如果您需要包含用户提供的内容,请参阅https://stackoverflow.com/a/37920555/645715 以获得使用 Base64 编码的更好答案

【讨论】:

  • 您能告诉我&lt;%-&lt;%= 之间的区别吗?为什么最后没有;
  • &lt;%= x %&gt; 直接插入 x 的值,&lt;%-x%&gt; 也对其进行 HTML 转义,因此像 &lt;&gt; 这样的字符不会被 HTML 解析器吃掉。
  • 在 Javascript 终端分号是可选的,但最好包含。
  • @prototype 真棒兄弟!拯救了我的一天! ^_^ 完美答案,想HTML逃跑很久了……
  • @prototype,你能告诉我为什么在客户端使用'JSON.stringify()'吗?因为节点会将数据作为对象的形式传递,而 stringify 只会将其转换为字符串,而不是我们需要一个对象,对吗?没有 JSON.stringify() 就不行
【解决方案2】:

这是预期的行为。您的模板引擎正在尝试从您的对象创建一个字符串,该字符串导致 [Object object]。如果你真的想传递这样的数据,我认为你通过对对象进行字符串化是正确的。

【讨论】:

  • JSON.stringify(someLargeObj)
【解决方案3】:

如果您正在使用模板,那么最好获取模板中的值,例如用户是否登录。您可以使用

获取发送本地数据
<script>
    window.user = <%- JSON.stringify(user || null) %>
</script>

从服务器端代码,您正在发送用户数据。

res.render('profile', {
    user: user.loggedin,
    title: "Title of page"
});

【讨论】:

    【解决方案4】:

    认为在将对象传递给 ejs 时有更好的方法,您不必处理 JSON.stringfy 和 JSON.parse 方法,这些方法有点棘手和混乱。相反,您可以使用 for in 循环来遍历对象的键,例如:

    如果你有一个像这样的层次结构的对象

    {
        "index": {
            "url": "/",
            "path_to_layout": "views/index.ejs",
            "path_to_data": [
                "data/global.json",
                {
                    "data/meta.json": "default"
                }
            ]
        },
        "home": {
            "url": "/home",
            "path_to_layout": "views/home/index.ejs",
            "path_to_data": [
                "data/global.json",
                {
                    "data/meta.json": "home"
                }
            ]
        },
        "about": {
            "url": "/about",
            "path_to_layout": "views/default.ejs",
            "path_to_data": [
                "data/global.json",
                {
                    "data/meta.json": "about"
                }
            ]
        }
    }
    

    在 EJS 端,您可以像这样循环 yourObject;

    <% if ( locals.yourObject) { %>
      <% for(key in yourObject) { %>
        <% if(yourObject.hasOwnProperty(key)) { %>
          <div> <a class="pagelist" href="<%= yourObject[key]['subkey'] %>"><%= key %></a></div>
        <% } %>
      <% } %>
    <% } %>
    

    对于本例,[key] 可以采用 'index'、'home' 和 'about' 值,而 subkey 可以是它的任何子项,例如 'url'、'path_to_layout'、'path_to_data'

    【讨论】:

      【解决方案5】:

      你得到的是这样的结果 [{'re': 'tg'}]

      你实际上需要循环它。见javascript while循环https://www.w3schools.com/js/js_loop_while.asp

      然后,用 ejs 在你的前端渲染它......我无法帮助,我使用 hbs

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-26
        • 2011-12-02
        • 1970-01-01
        • 2019-10-28
        相关资源
        最近更新 更多