Передача объекта клиенту в node / express + ejs?

у меня есть довольно большой объект, который мне нужно передать функции в клиентском скрипте. Я пробовал использовать JSON.stringify, но столкнулись с несколькими проблемами с этим подходом-в основном связанными с производительностью. Возможно ли сделать что-то подобное в ejs?

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

и в моем клиентском скрипте я бы передал этот объект такой функции, как so

<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>

5 ответов


это ожидаемое поведение. Ваш механизм шаблонов пытается создать строку из вашего объекта, которая приводит к [Object object]. Если вы действительно хотите передать такие данные, я думаю,что вы сделали правильную вещь, построив объект.


В Узел.js:

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

в EJS по:

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

БЕЗОПАСНОСТЬ: не используйте это для отображения объекта с пользовательскими данными. Возможно для кого-то вроде Маленькие Столы Бобби чтобы включить подстроку, которая разбивает строку JSON и запускает исполняемый тег или что-то еще. Например, в узле.js это выглядит довольно невинно...

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

но может привести к скрипту, предоставленному клиентом выполняется в браузерах пользователя, если они вводят цвет, такой как:

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

Если вам нужно включить пользовательский контент, см. https://stackoverflow.com/a/37920555/645715 для лучшего ответа, используя кодировку Base64


Если вы используете templating, то было бы намного лучше получить значения в шаблоне, например, независимо от того, вошел ли пользователь или нет. Вы можете получить локальные данные отправки, используя

<script>
    window.user = <%- JSON.stringify(user || null) %>
</script>

из кода на стороне сервера, вы отправляете данные пользователя.

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

У вас есть такой результат [{'re':'tg'}]

вам действительно нужно зациклить его. См. javascript while loop https://www.w3schools.com/js/js_loop_while.asp

затем визуализируйте его в передней части с помощью ejs... я не могу помочь в этом, я использую hbs


думаю, что есть гораздо лучший способ при передаче объекта в ejs, вам не придется иметь дело с JSON.stringfy и JSON.методы разбора, они немного сложны и запутанны. Вместо этого вы можете использовать цикл 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' значения и может быть любой из его детей, например, 'URL-адрес','path_to_layout','путь_к_данным'