сырье против html_safe против h до эскейп html

323

Предположим, у меня есть следующая строка

@x = "<a href='#'>Turn me into a link</a>"

На мой взгляд, я хочу, чтобы ссылка отображалась. То есть я не хочу, чтобы все в @x было экранировано и отображалось в виде строки. Какая разница между использованием

<%= raw @x %>
<%= h @x %>
<%= @x.html_safe %>

?

grautur
источник
Поскольку никто не упомянул об этом, я подумал, что я бы также упомянул, <%== @x %>что это псевдоним <%= raw(@x) %> edgeguides.rubyonrails.org/…
CTS_AE

Ответы:

386

Учитывая Rails 3:

html_safeна самом деле «устанавливает строку» как HTML Safe (это немного сложнее, но это в основном так). Таким образом, вы можете возвращать строки HTML Safe от помощников или моделей по желанию.

hможет использоваться только из контроллера или представления, так как это от помощника. Это заставит выход быть экранированным. На самом деле это не рекомендуется, но вы, скорее всего, больше не будете его использовать: единственное использование - «отменить» html_safeобъявление, довольно необычно.

Предварительное добавление выражения к rawфактически эквивалентно вызову, to_sсвязанному с html_safeним, но оно объявляется помощником, точно так же, как hего можно использовать только в контроллерах и представлениях.

« SafeBuffers and Rails 3.0 » - хорошее объяснение того, как работает SafeBuffers (класс, который творит html_safeмагию).

Фабио Батиста
источник
42
Я не сказал бы, что hкогда-либо будет осуждается. Использование "Hi<br/>#{h@ user.name}".html_safeявляется довольно распространенным и приемлемым использованием.
maletor
1
@Maletor интересное использование, хотя я все еще думаю, что он попадает в категорию "необычных".
Фабио Батиста,
5
Строка # html_safe фактически возвращает экземпляр ActiveSupport :: SafeBuffer, который оборачивает исходную строку и является #html_safe? , Исходная строка не становится #html_safe? после вызова #html_safe.
jmaxyz
9
Обратите внимание, что есть небольшая разница между rawи html_safeна практике: raw(nil)возвращает пустую строку, а nil.html_safeвыдает исключение.
Ван дер Хоорн
2
hне будет "возвращать" объявление html_safe. Когда строка есть html_safe, hничего не будет делать.
GuiGS
113

Я думаю , что стоит повторить: html_safeэто не HTML-бежать вашу строку. Фактически, это предотвратит выход вашей строки.

<%= "<script>alert('Hello!')</script>" %>

поставит:

&lt;script&gt;alert(&#x27;Hello!&#x27;)&lt;/script&gt;

в ваш источник HTML (да, так безопасно!), а:

<%= "<script>alert('Hello!')</script>".html_safe %>

появится диалоговое окно с предупреждением (вы уверены, что это то, что вы хотите?). Таким образом, вы, вероятно, не хотите вызывать html_safeлюбые введенные пользователем строки.

roasm
источник
81
Другими словами, html_safe - это не «пожалуйста, сделайте этот HTML-код безопасным», а наоборот - это вы, программист, говорите рельсам, что «эта строка безопасна для HTML, обещайте!»
PaulMurrayCbr
на самом деле я пришел сюда, чтобы выяснить, действительно ли он делает unescape или просто делает отметку, что он не нужен to_escape . Разница Ну что ж, тогда читать исходный код.
Саймон Б.
Понятие "html_safe" - это просто мета-флаг в строке. Маркировка что - то , как html_safeэто не избежать ни экранирования в . В то время как конечный результат маркировки что - то , как не HTML безопасно, а затем , используя неявное вытекание из Еврорадио <% = тег, может быть таким же , как неэкранированные данные , а затем повторно спасаясь его на выходе, функционально он не будет ни делать. Вроде как разница (6 * -1 * -1), против 6.
Бен Циттлау
46

Разница между Rails html_safe()и raw(). Иегуда Кац написал отличную статью об этом, и она сводится к следующему:

def raw(stringish)

  stringish.to_s.html_safe

end

Да, raw()это обертка вокруг, html_safe()которая вызывает ввод для String и затем вызывает html_safe()его. Это также тот случай, когда он raw()является помощником в модуле, тогда html_safe()как метод класса String создает новый экземпляр ActiveSupport :: SafeBuffer, в котором есть @dirtyфлаг.

Обратитесь к разделу " Rails 'html_safe против raw ".

Pankhuri
источник
30
  1. html_safe :

    Отмечает строку как надежную. Он будет вставлен в HTML без дополнительного экранирования.

    "<a>Hello</a>".html_safe
    #=> "<a>Hello</a>"
    
    nil.html_safe
    #=> NoMethodError: undefined method `html_safe' for nil:NilClass
  2. raw :

    rawэто просто обертка вокруг html_safe. Используйте, rawесли есть вероятность, что строка будет nil.

    raw("<a>Hello</a>")
    #=> "<a>Hello</a>"
    
    raw(nil)
    #=> ""
  3. hпсевдоним для html_escape:

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

    В Rails 3 и выше он используется по умолчанию, поэтому вам не нужно использовать этот метод явно

Дипак Махакале
источник
14

Лучший безопасный способ: <%= sanitize @x %>

Это позволит избежать XSS!

Гильерме Й. Хатано
источник
2

В терминах Simple Rails:

h удалите HTML-теги в числовые символы, чтобы рендеринг не нарушал ваш HTML

html_safe устанавливает логическое значение в строке так, чтобы строка рассматривалась как сохранение HTML

raw Конвертирует в html_safe в строку

user3118220
источник
hЭто html_safeозначает, что HTML отображается как есть.
Дэйв Ньютон
Ответ правильный: h is html_escape ... из базы кода Rails
notapatch