Не избегайте HTML в рубине на рельсах - PullRequest
49 голосов
/ 14 октября 2010

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)) %>

Ответы [ 2 ]

86 голосов
/ 14 октября 2010

Вы можете использовать .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) %>
3 голосов
/ 23 апреля 2015

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...