Не избежать HTML в рубине на рельсах

Обновить

December 2018

Просмотры

27.2k раз

46

Рельсы 3 кажется, избежать все, включая HTML. Я попытался с помощью сырец (), но она по-прежнему ускользает от 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)) %>

2 ответы

3

Я столкнулся с теми же вещами , и обнаружил более безопасное решение , чем использование 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 , во всех отношениях , кроме одного: Когда вы добавляете строку в SafeBuffer (по телефону + или <<), что другие строки HTML-экранированы перед оно добавляется к SafeBuffer. Когда вы добавляете другой SafeBuffer к SafeBuffer, не миновать не произойдет. Rails оказывает все представления под капотом , используя SafeBuffers, поэтому обновленный метод выше заканчивает предоставление Rails с SafeBuffer , что мы контролируемых выполнить побег на long_message« по мере необходимости» , а не «всегда».

Теперь, кредит на этот ответ идет полностью Henning Коха, и объясняется гораздо более подробно на Все , что вы знаете о html_safe неправильно - мое резюме выше попыток только обеспечить суть объяснения в том случае, если эта связь никогда не умирает ,

84

Вы можете использовать , .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) %>