JSONをサーバーとフロント側で安全に共有する

  • 72
    Like
  • 5
    Comment

こんな感じかなと思いつつ、ベスト・プラクティスってありますか?

追記: @ngyuki さんがコメントしてくださったものの方がよさそうなのでそちらを紹介しておきます

属性値として設定してHTML escapeする

server
this.render("index", {
  initialData: JSON.stringify(initialData)
});
handlebars
<script id="initial-data" type="text/plain" data-json="{{initialData}}"></script>
browser
var initialState = JSON.parse(document.getElementById('initial-data').getAttribute('data-json'));

  • 最初に書いていたもの

JSON.stringifyしたのをscriptタグ内に入れつつscriptタグを閉じられるのを防ぐために</をエスケープする

  • server(node)
this.render("index", {
  initialData: JSON.stringify(initialData).replace(/<\//g, '<\\/')
});
<!-- handlebars -->
<script id="initial-data" type="application/json">{{{initialData}}}</script>
  • browser
var initialState = JSON.parse(document.getElementById('initial-data').innerText);

Reactでserver-side-renderingしようとする時に必要になったので...

3882contribution

var initialState = JSON.parse(document.getElementById('initial-data').innerText);

innerText ではなくて innerHTML ではないでしょうか?

3882contribution

動的に書き出すなら script タグより属性の方が安全かもしれません。

server
this.render("index", {
  initialData: JSON.stringify(initialData)
});
handlebars
<script id="initial-data" type="text/plain" data-json="{{initialData}}"></script>
browser
var initialState = JSON.parse(document.getElementById('initial-data').getAttribute('data-json'));
5393contribution

@ngyuki

ありがとうございます!
属性に入れてHTML escapeする方が安全でよいですね!
こちらに修正させていただきます。

innerHTMLの件ですが、scriptの中はtextContentとして扱えるのかなと思ってinnerTextにしたのですが、JSON.stringifyしたものが入ってくる場合で、innerTextだと問題になったりすることってあるのでしょうか?

3882contribution

@koba04

innerTextだと問題になったりすることってあるのでしょうか?

innerText は FireFox で動かなかったと思います。

5393contribution

@ngyuki
そうでした、、
むしろtextContentが標準で、IEはtextContentが使えないからinnerTextで代用する感じでしたね...(挙動が違うみたいですが)。
ありがとうございます!