Не избегайте html в рубине на рельсах
rails 3, похоже, избегает всего, включая html. Я попытался использовать raw(), но он все еще избегает html. Есть ли обходной путь? Это мой помощник, который я использую (/helpers/application_helper.rb):
module ApplicationHelper
def good_time(status = true)
res = ""
if status == true
res << "Status is true, with a long message attached..."
else
res << "Status is false, with another long message"
end
end
end
Я вызываю помощника в своем представлении, используя этот код:
<%= raw(good_time(true)) %>
Ответы
Ответ 1
Вы можете использовать .html_safe
следующим образом:
def good_time(status = true)
if status
"Status is true, with a long message attached...".html_safe
else
"Status is false, with another long message".html_safe
end
end
<%= good_time(true) %>
Ответ 2
Я столкнулся с этим и обнаружил более безопасное решение, чем использование html_safe
, особенно после того, как вы введете строки, которые являются динамическими.
Во-первых, обновленный код:
def good_time(long_message1, long_message2, status = true)
html = "".html_safe
html << "Status is #{status}, "
if status
html << long_message1
else
html << long_message2
end
html
end
<%= good_time(true) %>
Это ускоряет содержимое long_message
, если оно небезопасно, но оставляет его незанятым, если оно безопасно.
Это позволяет "long message for success & such."
отображать правильно, но также ускоряет "malicious message <script>alert('foo')</script>"
.
Объяснение сводится к этому - 'foo'.html_safe
возвращает ActiveSupport:: SafeBuffer, который действует как String любым способом, кроме одного: когда вы добавляете String в SafeBuffer (путем вызова + или < <), что другая String выведена из HTML, прежде чем она будет добавлена в SafeBuffer. Когда вы добавляете другой SafeBuffer в SafeBuffer, экранирование не произойдет. Rails отображает все ваши представления под капотом с помощью SafeBuffers, поэтому обновленный выше метод заканчивает предоставление Rails с помощью SafeBuffer, который мы контролировали, чтобы выполнить escaping на long_message
"по мере необходимости", а не "всегда".
Теперь, кредит для этого ответа полностью относится к Хеннинг Коху и более подробно объясняется в Все, что вы знаете о html_safe, неверно - мое резюме выше пытается только предоставить суть объяснения в случае, когда эта ссылка когда-либо умирает.