原始 vs.html_safe vs. h 取消转义 HTML

raw vs. html_safe vs. h to unescape html

提问人:grautur 提问时间:11/23/2010 最后编辑:Jamison Dancegrautur 更新时间:1/18/2022 访问量:308154

问:

假设我有以下字符串

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

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

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

?

Ruby-on-Rails ERB (英语

评论

6赞 CTS_AE 2/13/2019
既然没有人提到它,我想我也会提到 edgeguides.rubyonrails.org/ 的别名......<%== @x %><%= raw(@x) %>

答:

404赞 Fábio Batista 11/23/2010 #1

考虑 Rails 3:

html_safe实际上“将字符串”设置为 HTML 安全(它比这复杂一点,但基本上就是这样)。这样,您可以随意从帮助程序或模型返回 HTML Safe 字符串。

h只能在控制器或视图中使用,因为它来自帮助程序。它将强制对输出进行转义。它并没有真正被弃用,但你很可能不会再使用它了:唯一的用法是“还原”一个声明,这很不寻常。html_safe

在表达式前面加上 with 实际上等同于调用 chained with on 它,但是在帮助程序上声明的,就像 一样,所以它只能在控制器和视图上使用。rawto_shtml_safeh

"SafeBuffers and Rails 3.0“很好地解释了 s(施展魔法的类)是如何工作的。SafeBufferhtml_safe

评论

45赞 maletor 7/20/2011
我不会说这永远不会被弃用。使用是很常见的,也是公认的用途。h"Hi<br/>#{h@ user.name}".html_safe
1赞 Fábio Batista 7/20/2011
@Maletor有趣的用法,尽管我仍然认为它属于“不寻常”的类别。
5赞 jmaxyz 4/13/2012
String#html_safe实际上返回一个 ActiveSupport::SafeBuffer 实例,该实例包装原始字符串并且是 #html_safe? 。原始字符串不会变成 #html_safe?在调用#html_safe之后。
10赞 Van der Hoorn 8/12/2013
请注意,在实践中,和之间存在细微的区别:返回一个空字符串,而抛出异常。rawhtml_saferaw(nil)nil.html_safe
2赞 GuiGS 5/27/2014
h不会“还原”html_safe声明。当字符串为 时,将不执行任何操作。html_safeh
129赞 roasm 9/13/2012 #2

我认为值得重复一遍:不会对你的字符串进行 HTML 转义。事实上,它会防止你的字符串被转义。html_safe

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

将把:

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

添加到您的 HTML 源代码中(是的,非常安全!),同时:

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

将弹出警报对话框(您确定这是您想要的吗?因此,您可能不想调用任何用户输入的字符串。html_safe

评论

109赞 PaulMurrayCbr 1/10/2014
换句话说,html_safe不是“请让这个html安全”,而是相反的 - 是程序员告诉rails“这个字符串是html安全的,承诺!
0赞 Simon B. 3/31/2015
实际上,我来这里是为了弄清楚它是否真的无法逃脱,或者它是否只是做了一个标记,表明它没有必要to_escape。有很大的不同。哦,好吧,那就去阅读源代码吧。
1赞 Ben Zittlau 8/23/2019
“html_safe”的概念只是字符串上的一个元标志。将某物标记为不会逃逸取消逃逸。虽然将某些内容标记为 HTML 安全,然后使用 ERB <%= 标记的隐式转义的最终结果可能与取消转义数据然后在输出时重新转义数据相同,但从功能上讲,它两者都不做。有点像 (6 * -1 * -1) 与 6 的差异。html_safe
53赞 Pankhuri 8/10/2013 #3

区别在于 Rails 和 .耶胡达·卡茨(Yehuda Katz)对此发表了一篇出色的文章,它实际上归结为:html_safe()raw()

def raw(stringish)

  stringish.to_s.html_safe

end

是的,是一个包装器,强制输入到 String 然后调用它。这也是一个模块中的帮助程序,而它是 String 类上的一个方法,它创建一个新的 ActiveSupport::SafeBuffer 实例——其中有一个标志。raw()html_safe()html_safe()raw()html_safe()@dirty

请参阅“Rails 的html_safe与.raw”。

3赞 user3118220 8/26/2015 #4

用 Simple Rails 术语来说:

h将 HTML 标记删除为数字字符,以便呈现不会破坏您的 HTML

html_safe在字符串中设置布尔值,以便将该字符串视为 HTML 保存

raw它将 html_safe 转换为字符串

评论

2赞 notapatch 10/3/2019
答案是正确的:h 是 html_escape ......来自 Rails 代码库
39赞 Deepak Mahakale 9/26/2016 #5
  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只是一个包装器.如果字符串有可能为 .html_saferawnil

    raw("<a>Hello</a>")
    #=> "<a>Hello</a>"
    
    raw(nil)
    #=> ""
    
  3. html_escapeh 别名:

    用于转义 HTML 标记字符的实用工具方法。使用此方法可转义任何不安全的内容。

    在 Rails 3 及更高版本中,默认使用它,因此您不需要显式使用此方法

28赞 Guilherme Y. Hatano 9/1/2017 #6

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

它将避免 XSS!

0赞 BenKoshy 1/18/2022 #7

短小精悍

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

坏:

user_input.html_safe # asking for trouble

好:

user_input.html_escape # or

h(user_input) # in some view

我们控制的输入:

trusted_input_only.html_safe

那应该没问题。但要小心你信任的输入是什么。它们只能从您的应用生成。