Ruby on Rails: как отобразить строку в виде HTML?


154

у меня есть

@str = "<b>Hi</b>"

и по моему мнению:

<%= @str %>

Что будет отображаться на странице: <b>Hi</b>когда я действительно хочу Привет . Что такое рубиновый способ «интерпретировать» строку как разметку HTML?


Изменить : случай, когда

@str = "<span class=\"classname\">hello</span>"

Если, на мой взгляд, я делаю

<%raw @str %>

Исходный код HTML - это <span class=\"classname\">hello</spanто, где я действительно хочу <span class="classname">hello</span>(без обратной косой черты, которой не хватает двойных кавычек). Какой лучший способ "убрать" эти двойные кавычки?


Вы также можете использовать синтаксис% Q [] для экранирования строк. например, %Q["quotation marks"] => "\"quotation marks\"" источник: en.wikibooks.org/wiki/Ruby_Programming/Syntax/… Не знаю, поможет ли это.
0112

Ответы:


328

ОБНОВИТЬ

По соображениям безопасности рекомендуется использовать sanitizeвместо html_safe. Ссылка на сайт


Происходит то, что в качестве меры безопасности Rails избегает вашей строки за вас, потому что в нее может быть встроен вредоносный код. Но если вы скажете Rails, что ваша строка есть html_safe, она пройдет через нее.

@str = "<b>Hi</b>".html_safe
<%= @str %>

ИЛИ

@str = "<b>Hi</b>"
<%= @str.html_safe %>

Использование rawотлично работает, но все, что он делает, это конвертирует строку в строку, а затем вызывает html_safe. Когда я знаю, что у меня есть строка, я предпочитаю вызывать html_safe напрямую, потому что он пропускает ненужный шаг и проясняет, что происходит. Подробная информация о экранировании строк и защите XSS находится в этом Asciicast .


Фантастика. Я не мог найти, как это сделать, даже после поиска в течение часа. Спасибо за Ваш ответ.
Салил

1
Я всегда использовал raw. Очень рад узнать об этом!
Jmcharnes

Дарить благодарности из будущего =)
Карлос Моралес

1
sanitize удаляется в соответствии со stackoverflow.com/questions/44575106/…
Youness

16

Используйте сырье :

<%=raw @str >

Но, как правильно говорит @ jmort253, подумайте, где на самом деле принадлежит HTML.


Привет, это решение работает, за исключением одного предупреждения: см. Отредактированный вопрос
Тим

14

Если вы railsиспользуете Erubis - самый крутой способ сделать это

<%== @str >

Обратите внимание на двойной знак равенства. См. Связанный вопрос на SO для получения дополнительной информации.



7

Вы смешиваете свою бизнес-логику с вашим контентом. Вместо этого я бы порекомендовал отправить данные на вашу страницу, а затем использовать что-то вроде JQuery, чтобы поместить данные туда, куда вам нужно.

Это дает преимущество, заключающееся в том, что весь ваш HTML-код хранится на тех HTML-страницах, к которым он относится, поэтому ваши веб-дизайнеры могут позже изменить HTML-код без необходимости пролистывать код на стороне сервера.

Или, если вы не хотите использовать JavaScript, вы можете попробовать это:

@str = "Hi"

<b><%= @str ></b>

По крайней мере, так ваш HTML находится на странице HTML, где он принадлежит.


Проблема в том, что мое приложение берет файл с плохой разметкой и «переводит» его через регулярные выражения в хорошую HTML-разметку для отправки в представление. Поэтому генерируемая HTML-разметка является динамической, поэтому я не знаю заранее, какие теги должны окружать @str. Где бы я выполнял эту «переводческую» работу, если бы не модели? Я думал, что у нас не должно быть обширного логического кода в представлениях.
Тим

1
Это действительно вопрос мнения. При разработке нового приложения я предпочитаю держать все как можно более чистым. Но часто мы должны работать в рамках того, что оставили нам другие. Если ваш источник данных возвращает HTML-разметку, возможно, стоит взглянуть на использование «raw», как описано в решении Майкла Стума.
jmort253

1
Если вы унаследовали поддержку какого-либо кода, и в коде есть области, которые плохо продумываются или имеют плохой дизайн, то в действительности вы несете ответственность за его очистку, чтобы сделать его более удобным для сопровождения. Оставить его таким, каким вы его нашли, - это хорошо, когда это отличный код для начала, но оставить его лучше, чем вы находили, это хорошо, когда он нуждается в работе. Частью моей работы является управление некоторыми устаревшими приложениями; Я фанат не чинить вещи, которые не сломаны, но они не могут быть легко улучшены из-за того, как они были написаны. Мне пришлось переписать большинство вызовов функций, но теперь работать намного проще.
Железный Человек

Вы не должны использовать JavaScript для своей HTML-интерполяции, если нет другой причины использовать JS. Это нарушит ваш сайт , не JS браузерах (да, там находятся некоторые).
Марнен Лайбоу-Козер

1
Разумеется, если вы разрешаете не экранированный контент, то вы можете сделать все возможное, чтобы гарантировать, что не будет злой разметки.
Макарио

6

Или вы можете попробовать метод CGI.unescapeHTML .

CGI.unescapeHTML "&lt;p&gt;This is a Paragraph.&lt;/p&gt;"
=> "<p>This is a Paragraph.</p>"

0

поскольку вы переводите и выбираете нужный код из дрянного закодированного файла, можете ли вы использовать content_tag в сочетании с вашим регулярным выражением.

Кража из api docs, вы можете интерполировать этот переведенный код в content_tag как:

<%= content_tag translated_tag_type.to_sym, :class => "#{translated_class}" do -%>
<%= translated_text %>
<% end -%>
# => <div class="strong">Hello world!</div>

Не зная вашего кода, такое мышление сделает ваш переведенный код слишком совместимым.


Я предполагаю, что translation_text - это фактический контент внутри div, верно? т.е. в примере это будет "Hello world!"? Что если в Translate_text больше HTML, то есть вложенных элементов div или span? Должен ли я вызывать content_tag много раз?
Тим

и ... извините, нажмите enter рано ... каждый вложенный div / span внутри по-прежнему является тегом content_tag, и вам все равно нужно его проверить, правда? Так как мы не можем видеть, что вы делаете с вашим необычным переводом ;-), я бы предположил, что вы ищете ВСЕ теги, независимо от того, находится ли регулярное выражение в «родительском» html ..., например, <ul>. Вы бы не поместили все лики в виде большой задницы для печати, не так ли? у каждого будет свой content_tag: li, текст правильный?
Пьяммер

0

@str = "<span class=\"classname\">hello</span>" Если, на мой взгляд, я делаю

<%raw @str %> Исходный код HTML - это <span class=\"classname\">hello</span>то, что я действительно хочу <span class="classname">hello</span>(без обратной косой черты, которая экранирует двойные кавычки). Какой лучший способ "убрать" эти двойные кавычки?

Решение: используйте двойные кавычки внутри одинарных кавычек (или одинарные внутри двойных), чтобы избежать обратной косой черты.

@str = '<span class="classname">hello</span>'
<%raw @str %>

0

Версия html_safe хорошо работает в Rails 4 ...

<%= "<center style=\"color: green; font-size: 1.1em\" > Administrators only </center>".html_safe if current_user.admin? %
>
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.