8

django webappでJSONデータを安全にレンダリングするにはどうすればよいですか?

django のサーバーで JSON データを生成し、その JSON データを django テンプレートでレンダリングします。JSON には、html のスニペットが含まれることがあります。ほとんどの場合、それで問題ありません</script>が、レンダリング時にタグが JSON データ内にある場合、周囲の JavaScript が破壊されます。

例えば...

サーバー上では、Python でこれを使用します。

template_data = {
    'my_json' : '[{"my_snippet": "<b>Happy HTML</b>"}]'
}
# pass the template data to the django template
return render_to_response('my_template.html', template_data, context_instance = c)

そして、テンプレートで

<script type="text/javascript">
var the_json = {{my_json|safe}};
</script>
... some html ...

結果のhtmlは正常に動作し、次のようになります。

<script type="text/javascript">
var the_json = [{"my_snippet": "<b>Happy HTML</b>"}];
</script>
... some html ...

ただし、サーバー上で JSON が次のようになると、問題が発生します。

template_data = {
    'my_json' : '[{"my_snippet": "Bad HTML</script>"}]'
}
return render_to_response('my_template.html', template_data, context_instance = c)

レンダリングすると、次のようになります。

<script type="text/javascript">
var the_json = [{"my_snippet": "Bad HTML</script>"}];
</script>
... some html ...

JSON コード内の終了スクリプト タグは、スクリプト ブロック全体を終了するものとして扱われます。そうすると、すべての JavaScript が壊れます。

考えられる解決策の 1 つは、テンプレート データをテンプレートに渡すときにチェックする</script>ことですが、もっと良い方法があるように感じます。

4

1 に答える 1

15

JSON を文字列として安全に挿入し、JSON.parse を呼び出します。

safeの代わりにescapejsを使用します。JavaScript への出力用に設計されています。

var the_json = '{{my_json|escapejs}}';

JavaScript オブジェクトを取得するにはJSON.parse、その文字列を呼び出す必要があります。これは、セキュリティ上の理由から、JSON エンコーディングをスクリプトにダンプして直接評価するよりも常に望ましい方法です。

私が使用しているクライアントに直接 Python オブジェクトを取得するための便利なフィルターは次のとおりです。

@register.filter
def to_js(value):
    """
    To use a python variable in JS, we call json.dumps to serialize as JSON server-side and reconstruct using
    JSON.parse. The serialized string must be escaped appropriately before dumping into the client-side code.
    """
    # separators is passed to remove whitespace in output
    return mark_safe('JSON.parse("%s")' % escapejs(json.dumps(value, separators=(',', ':'))))

そして、次のように使用します。

var Settings = {{ js_settings|to_js }};
于 2013-01-12T05:25:00.017 に答える