Raw vs. html_safe vs. h来解转义HTML

假设我有下面的字符串

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

在我的视图中,我希望显示一个链接。也就是说,我不希望@x中的所有内容都未转义并显示为字符串。使用有什么区别

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

?

299602 次浏览

考虑Rails 3:

html_safe实际上“设置字符串”为HTML安全(它比这更复杂一点,但基本上就是这样)。通过这种方式,您可以随意从helper或模型返回HTML安全字符串。

h只能从控制器或视图中使用,因为它来自一个helper。它将强制输出转义。它并没有真正被弃用,但你很可能不会再使用它:唯一的用法是“恢复”html_safe声明,非常不寻常。

在表达式前加上raw实际上相当于调用带有html_safeto_s,但它是在帮助器上声明的,就像h一样,因此它只能用于控制器和视图。

"SafeBuffers和Rails 3.0"很好地解释了__abc0(执行html_safe魔法的类)是如何工作的。

我认为它值得重复: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

区别在于Rails的html_safe()raw()。Yehuda Katz在这方面有一篇很棒的文章,它可以归结为:

def raw(stringish)


stringish.to_s.html_safe


end

是的,raw()html_safe()的包装器,它强制输入为String,然后对其调用html_safe()。还有一种情况是,raw()是模块中的一个helper,而html_safe()是String类中的一个方法,它创建了一个新的ActiveSupport::SafeBuffer实例——其中有一个@dirty标志。

参考“Rails的html_safe vs. raw”。

在简单Rails术语中:

h删除html标签为数字字符,这样渲染就不会破坏你的html

html_safe在字符串中设置一个布尔值,以便将字符串视为html保存

raw将html_safe转换为字符串

  1. < p > 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 is just a wrapper around html_safe. Use raw if there are chances that the string will be nil.

    raw("<a>Hello</a>")
    #=> "<a>Hello</a>"
    
    
    raw(nil)
    #=> ""
    
  3. h alias for html_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

最安全的方法是:<%= sanitize @x %>

它将避免XSS!

简洁明了

让我们假设我们不能相信用户输入。

缺点:

user_input.html_safe # asking for trouble

好:

user_input.html_escape # or

h(user_input) # in some view

我们控制的输入:

trusted_input_only.html_safe

应该没问题。但是要注意您的可信输入是什么。它们必须只能从你的应用程序中生成。