2013-01-12 5 views
8

Jak bezpiecznie renderować dane JSON w webmasterze django?Bezpieczne używanie JSON-a z html wewnątrz JSON-a w szablonach Django

Na serwerze w django generuję dane JSON, a następnie renderuję dane JSON w szablonie django. JSON sporadycznie zawiera fragmenty html. Najczęściej jest to w porządku, jednak jeśli znacznik </script> znajduje się w danych JSON, gdy jest renderowany, niszczy otaczający javascript.

Na przykład ...

Na serwerze, w python Muszę to:

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) 

A potem w szablonie:

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

The w wyniku html działa dobrze i wygląda tak:

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

jednak pojawią się problemy, gdy na serwerze, JSON wygląda następująco:

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

Teraz, kiedy jest renderowane, dostaniesz:

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

Tag zamykającego skryptu w kodzie JSON jest traktowany jako zamknięcie całego bloku skryptu. Cały twój javascript się zepsuje.

Jednym z możliwych rozwiązań jest sprawdzenie, czy </script> przekazuje dane szablonu do szablonu, ale mam wrażenie, że istnieje lepszy sposób.

+0

Można go służyć jako json (za pośrednictwem AJAX) lub podawaj go jako plik javascript (następnie dołącz go za pomocą znacznika skryptu). – DanielB

Odpowiedz

14

bezpiecznie włożyć JSON jako ciąg znaków, a następnie zadzwonić JSON.parse na nim

Korzystanie escapejs zamiast bezpieczne. Jest przeznaczony do wysyłania do JavaScript.

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

Aby uzyskać obiekt JavaScript Następnie należy zadzwonić JSON.parse tego łańcucha. Jest to zawsze lepsze niż zrzucenie kodu JSON do skryptu i dokonanie jego bezpośredniej oceny ze względów bezpieczeństwa.

Przydatny filtr, aby uzyskać obiektów Pythona bezpośrednio do klienta, które używam to:

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

i używać go lubię:

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

Jeśli to zrobisz, 'the_json' stanie się ciągiem, a nie obiektem json javascript. – speedplane

+1

Możesz zrobić 'var the_json = JSON.parse ({{my_json | escapejs}})' – DanielB

+1

Myślę, że powinieneś zacytować go w następujący sposób: 'var the_json = JSON.parse ('{{my_json | escapejs}}') ' – speedplane

Powiązane problemy