web-dev-qa-db-ja.com

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);
});

クライアントスクリプトでは、このオブジェクトを次のような関数に渡します。

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

それが予想される動作です。テンプレートエンジンは、オブジェクトから[オブジェクトオブジェクト]につながる文字列を作成しようとしています。そのようなデータを本当に渡したい場合、オブジェクトを文字列化することで正しいことをしたと思います。

11
Pickels

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エンコードを使用したより良い回答があります。

68
prototype

オブジェクトを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」の値を取り、サブキーは「url」、「path_to_layout」、「path_to_data」などの子のいずれかです。

1
btargac

テンプレートを使用している場合、たとえばユーザーがサインインしているかどうかなど、テンプレートの値を取得する方がはるかに良いでしょう。を使用して送信ローカルデータを取得できます

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

サーバー側のコードから、ユーザーデータを送信しています。

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

あなたが持っているのは、このような結果です[{'re': 'tg'}]

実際にループする必要があります。 javascript while loopを参照してください https://www.w3schools.com/js/js_loop_while.asp

次に、ejsを使用してフロントエンドでレンダリングします。

0
Mimigirl