2013-01-12 27 views
8

django WebアプリケーションでJSONデータを安全にレンダリングするにはどうすればよいですか?安全にDjangoテンプレートのJSON内でJSONをhtmlで使用する

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>をチェックすることですが、より良い方法があるように感じます。

+0

あなたは(AJAX経由)JSONとしてそれを提供することができたりjavascriptファイルとして提供します(スクリプトタグを使用して組み込みます)。 – DanielB

答えて

14

は安全に文字列としてJSONを挿入し、それ

代わりに金庫の使用escapejsにJSON.parseを呼び出します。 JavaScriptへの出力用に設計されています。

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

あなたはその文字列にJSON.parseを呼び出す必要がJavaScriptのオブジェクトを取得します。これは、セキュリティ上の理由から、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 }}; 
+0

これを行うと 'the_json'は文字列になり、javascript jsonオブジェクトにはなりません。 – speedplane

+1

あなたは 'var the_json = JSON.parse({{my_json | escapejs}})' – DanielB

+1

と書くことができます。このように引用する必要があると思います: 'var the_json = JSON.parse( '{{my_json | escapejs}}' ) ' – speedplane

関連する問題