Передача HTML в шаблон с помощью Flask / Jinja2

#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. Не очень безопасно!