Suppose I have the following string
@x = "<a href="#">Turn me into a link</a>"
In my view, I want a link to be displayed. That is, I don’t want everything in @x to be unescaped and displayed as a string. What’s the difference between using
<%= raw @x %>
<%= h @x %>
<%= @x.html_safe %>
?
1
7 Answers
Considering Rails 3:
html_safe
actually “sets the string” as HTML Safe (it’s a little more complicated than that, but it’s basically it). This way, you can return HTML Safe strings from helpers or models at will.
h
can only be used from within a controller or view, since it’s from a helper. It will force the output to be escaped. It’s not really deprecated, but you most likely won’t use it anymore: the only usage is to “revert” an html_safe
declaration, pretty unusual.
Prepending your expression with raw
is actually equivalent to calling to_s
chained with html_safe
on it, but is declared on a helper, just like h
, so it can only be used on controllers and views.
“SafeBuffers and Rails 3.0” is a nice explanation on how the SafeBuffer
s (the class that does the html_safe
magic) work.
6
I wouldn’t say that
h
will ever be deprecated. Using"Hi<br/>#{[email protected] user.name}".html_safe
is quite common and an accepted use.– maletor@Maletor interesting usage, though I still think it falls into the “unusual” category.
String#html_safe actually returns an instance of ActiveSupport::SafeBuffer which wraps the original string and is #html_safe? . The original string does not become #html_safe? after calling #html_safe on it.
– jmaxyzNote that there is a subtle difference between
raw
andhtml_safe
in practice:raw(nil)
returns an empty string, whilenil.html_safe
throws an exception.h
will not “revert” an html_safe declaration. When an string ishtml_safe
,h
will do nothing.– GuiGS
I think it bears repeating: html_safe
does not HTML-escape your string. In fact, it will prevent your string from being escaped.
<%= "<script>alert('Hello!')</script>" %>
will put:
<script>alert('Hello!')</script>
into your HTML source (yay, so safe!), while:
<%= "<script>alert('Hello!')</script>".html_safe %>
will pop up the alert dialog (are you sure that’s what you want?). So you probably don’t want to call html_safe
on any user-entered strings.
3
In other words, html_safe is not “please make this html safe”, it’s the opposite – it is you the programmer telling rails that “this string is html safe, promise!”
actually I came here to figure out if it actually does unescape or if it just makes a mark that it is not necessary to_escape. Quite a difference. Oh well, off to read the source code then.
– Simon B.The concept of “html_safe” is just a meta flag on the string. Marking something as
html_safe
does not escape nor unescape. While the end result of marking something as not HTML safe, and then using the implicit escaping of the ERB <%= tag, might be the same as unescaping data and then re-escaping it on output, functionally it’s doing neither. Kind of like the difference of (6 * -1 * -1), vs. 6.
The difference is between Rails’ html_safe()
and raw()
. There is an excellent post by Yehuda Katz on this, and it really boils down to this:
def raw(stringish)
stringish.to_s.html_safe
end
Yes, raw()
is a wrapper around html_safe()
that forces the input to String and then calls html_safe()
on it. It’s also the case that raw()
is a helper in a module whereas html_safe()
is a method on the String class which makes a new ActiveSupport::SafeBuffer instance — that has a @dirty
flag in it.
Refer to “Rails’ html_safe vs. raw“.
0
html_safe
:Marks a string as trusted safe. It will be inserted into HTML with no additional escaping performed.
"<a>Hello</a>".html_safe #=> "<a>Hello</a>" nil.html_safe #=> NoMethodError: undefined method `html_safe' for nil:NilClass
raw
:raw
is just a wrapper aroundhtml_safe
. Useraw
if there are chances that the string will benil
.raw("<a>Hello</a>") #=> "<a>Hello</a>" raw(nil) #=> ""
h
alias forhtml_escape
:A utility method for escaping HTML tag characters. Use this method to escape any unsafe content.
In Rails 3 and above it is used by default so you don’t need to use this method explicitly
1
The most straight forward explanation IMO
– stevec
The best safe way is: <%= sanitize @x %>
It will avoid XSS!
In Simple Rails terms:
h
remove html tags into number characters so that rendering won’t break your html
html_safe
sets a boolean in string so that the string is considered as html save
raw
It converts to html_safe to string
2
h
ishtml_safe
, which means the HTML is rendered as-is.The answer is correct: h is html_escape … from the Rails code base
Short and Simple
Let’s assume we can’t trust user input.
Bad:
user_input.html_safe # asking for trouble
Good:
user_input.html_escape # or
h(user_input) # in some view
Inputs we control:
trusted_input_only.html_safe
that should be fine. but be careful what your trusted inputs are. They must only be generated from your app.
Since nobody mentioned it I figured I’d also mention there’s
<%== @x %>
which is an alias to<%= raw(@x) %>
edgeguides.rubyonrails.org/…