2017-09-26 10 views
2

私たちには、外部JavaScriptファイルを含むサーバー側レンダリングHTMLページがあります。そのファイル内のコードをトリガーするために、我々は関数を呼び出すと、(JSONの形式で)いくつかの動的なデータを渡したい:Nunjucksを使用して安全にJSONをインライン<script>にレンダリングする方法はありますか?

<script src="/static/foo/bar.js"></script> 
<script> 
    foo.bar.init({biz: 42, qux: "quux"}); 
</script> 

我々はNunjucksテンプレートからこれをレンダリングすると、JSONオブジェクトを渡しています文脈で値dataとして。これには、ユーザー提供のコンテンツを含む任意のデータを含めることができます。

<>&は(Nunjucksの自動エスケープのおかげで)エスケープされているので、これは、安全であるが、動作しません:

foo.bar.init({{ data | dump }}); 

これは動作しますが、JSONの文字列がテキスト</script>が含まれている可能性があるため、安全ではありません:

foo.bar.init({{ data | dump | safe }}); 

NunjucksがこのJSONをレンダリングして安全に正しく解釈できるようにする方法を教えてください。解決しなければならない問題のように聞こえますが、私はどこでもプレミアソリューションを見つけることができません。

答えて

0

今のところ、これを行う:

/** 
    * Returns a JSON stringified version of the value, safe for inclusion in an 
    * inline <script> tag. The optional argument 'spaces' can be used for 
    * pretty-printing. 
    * 
    * Output is NOT safe for inclusion in HTML! If that's what you need, use the 
    * built-in 'dump' filter instead. 
    */ 
    env.addFilter('json', function (value, spaces) { 
    if (value instanceof nunjucks.runtime.SafeString) { 
     value = value.toString() 
    } 
    const jsonString = JSON.stringify(value, null, spaces).replace(/</g, '\\u003c') 
    return nunjucks.runtime.markSafe(jsonString) 
    }) 

使用法:

<script src="/static/foo/bar.js"></script> 
<script> 
    foo.bar.init({{ data | json }}); 
</script> 

より良い解決策はまだ歓迎します。

関連する問題