#html #python-3.x #flask #flask-wtforms
#python #jinja2 #flask
Вопрос:
Я создаю администратора для Flask и SQLAlchemy, и я хочу передать HTML для разных входных данных в мое представление, используя render_template
. Похоже, что структура шаблонов автоматически экранирует HTML, поэтому все <"'>
символы преобразуются в объекты HTML. Как я могу отключить это, чтобы HTML отображался правильно?
Ответ №1:
Чтобы отключить автоэскейпинг при отображении значения, используйте |safe
фильтр.
{{ something|safe }}
Делайте это только с данными, которым вы доверяете, поскольку рендеринг ненадежных данных без экранирования является уязвимостью межсайтового скриптинга.
Ответ №2:
MarkupSafe обеспечивает поведение автоэскейпинга Jinja. Вы можете импортировать Markup
и использовать его, чтобы объявить значение HTML безопасным из кода:
from markupsafe import Markup
value = Markup('<strong>The HTML String</strong>')
Передайте это шаблонам, и вам не нужно использовать |safe
для этого фильтр.
Ответ №3:
Из раздела Jinja docs экранирование HTML:
Когда включено автоматическое экранирование, все экранируется по умолчанию, за исключением значений, явно помеченных как безопасные. Они могут быть отмечены либо приложением, либо в шаблоне с помощью
|safe
фильтра.
Пример:
<div class="info">
{{data.email_content|safe}}
</div>
Ответ №4:
Когда у вас много переменных, которые не нуждаются в экранировании, вы можете использовать блок autoescape
переопределения:
{% autoescape false %}
{{ something }}
{{ something_else }}
<b>{{ something_important }}</b>
{% endautoescape %}
Ответ №5:
В частности, для обработки разрывов строк я перепробовал несколько вариантов, прежде чем окончательно согласиться на это:
{% set list1 = data.split('n') %}
{% for item in list1 %}
{{ item }}
{% if not loop.last %}
<br/>
{% endif %}
{% endfor %}
Самое приятное в этом подходе то, что он совместим с автоматическим экранированием, оставляя все красивым и безопасным. Его также можно комбинировать с фильтрами, такими как urlize.
Конечно, это похоже на ответ Хельге, но не требует макроса (полагаясь вместо этого на встроенную split
функцию Jinja), а также не добавляет ненужный <br/>
после последнего элемента.
Ответ №6:
Некоторые люди, похоже, отключают автоэскейп, что создает риски для безопасности при манипулировании строковым отображением.
Если вы хотите только вставить несколько разрывов строк в строку и преобразовать их в <br />
, тогда вы можете использовать макрос jinja, например:
{% macro linebreaks_for_string( the_string ) -%}
{% if the_string %}
{% for line in the_string.split('n') %}
<br />
{{ line }}
{% endfor %}
{% else %}
{{ the_string }}
{% endif %}
{%- endmacro %}
и в вашем шаблоне просто вызовите это с помощью
{{ linebreaks_for_string( my_string_in_a_variable ) }}
Ответ №7:
Используйте safe
фильтр в своем шаблоне, а затем очистите HTML с bleach
помощью библиотеки в вашем представлении. Используя bleach, вы можете внести в белый список HTML-теги, которые вам нужно использовать.
Насколько я знаю, это самый безопасный. Я попробовал как safe
фильтр, так и Markup
класс, и оба способа позволили мне выполнить нежелательный JavaScript. Не очень безопасно!