2013-01-12 1 views
8

Wie können Sie JSON-Daten in einer Django-Webanwendung sicher rendern?Sicheres Verwenden von JSON mit HTML innerhalb des JSON in Django Templates

Auf dem Server in Django erzeuge ich JSON-Daten und rendern dann diese JSON-Daten in einer Django-Vorlage. Der JSON enthält gelegentlich Snippets von HTML. Die meiste Zeit ist das in Ordnung, aber wenn das </script> Tag in den JSON-Daten ist, wenn es gerendert wird, zerstört es das umgebende Javascript.

Zum Beispiel ...

Auf dem Server, in Python das ich haben werden:

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) 

Und dann in der Vorlage:

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

Der resultierende HTML funktioniert gut und sieht so aus:

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

aber Sie Probleme, wenn auf dem Server, die JSON wie folgt aussieht:

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

Nun, wenn es gemacht ist, erhalten Sie:

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

Das schließende Skript-Tag innerhalb des JSON-Codes wird als Schließen des gesamten Skriptblocks behandelt. Alle Ihre Javascript werden dann brechen.

Eine mögliche Lösung ist zu überprüfen, </script> beim Übergeben der Vorlage Daten an die Vorlage, aber ich habe das Gefühl, es gibt einen besseren Weg.

+0

Man könnte es als json dienen (via AJAX) oder Serviere es als Javascript-Datei (dann schließe es mit einem Script-Tag ein). – DanielB

Antwort

14

einfügen sicher die JSON als String, und rufen Sie dann JSON.parse auf sie

Verwenden escapejs statt sicher. Es ist für die Ausgabe in JavaScript ausgelegt.

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

um ein JavaScript-Objekt erhalten Sie dann müssen JSON.parse auf dieser Zeichenfolge aufzurufen. Dies ist immer vorzuziehen, als eine JSON-Codierung in Ihr Skript zu schreiben und diese aus Sicherheitsgründen direkt auszuwerten.

Eine nützliche Filter Python-Objekte direkt an den Client, die ich ist benutzen Sie dies: es mag

@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=(',', ':')))) 

und Verwendung:

var Settings = {{ js_settings|to_js }}; 
+0

Wenn Sie das tun, wird 'the_json' zu einer Zeichenkette und nicht zu einem Javascript-json-Objekt. – speedplane

+1

Sie könnten 'var the_json = JSON.parse ({{my_json | escapejs}})' – DanielB

+1

Ich denke, Sie müssen es so zitieren: 'var the_json = JSON.parse ('{{my_json | escapejs}}') ' – speedplane