【问题标题】:How to HTML encode/escape a string? Is there a built-in?如何对字符串进行 HTML 编码/转义?有内置的吗?
【发布时间】:2010-10-16 03:05:05
【问题描述】:

我有一个不受信任的字符串,我想在 HTML 页面中显示为文本。我需要将字符“<”和“&”转义为 HTML 实体。越少大惊小怪越好。

我使用的是 UTF8,不需要其他实体来处理重音字母。

Ruby 或 Rails 中是否有内置函数,还是我应该自己开发?

【问题讨论】:

  • According to the OWASP,以下六个字符应转义以在 HTML 元素内容中进行适当的 XSS 保护:&<>"'/

标签: html ruby-on-rails ruby escaping encode


【解决方案1】:

检查 Ruby CGI 类。有一些方法可以对 HTML 和 URL 进行编码和解码。

CGI::escapeHTML('Usage: foo "bar" <baz>')
# => "Usage: foo &quot;bar&quot; &lt;baz&gt;"

【讨论】:

  • 谢谢,这很棒,因为它可以从控制器中完成。当然,我不会那样做。
  • 这在功能/集成测试中很有用,用于检查插入模板的内容的正确性(当内容应该是 HTML 转义时)。
  • 如果内容显示在客户网站上,而不是您自己的网站(您无法控制视图),在插入数据库之前转义 html 有什么问题?还有其他解决方法吗?
  • 正确 - 在进入数据库之前转义很棒。您只是想确保在添加之前没有任何旧的未转义的黑客......
  • 我更喜欢它的同义词:CGI.escape_html
【解决方案2】:

h 辅助方法:

<%=h "<p> will be preserved" %>

【讨论】:

  • 嗯,它也转义了>,这是不必要的,但它会做。
  • 您可以使用括号来打印一些带 h 和一些不带的。 " %>
  • 现在这太傻了。我不在乎它是否逃脱了。我只是注意到它不是 html 规范所必需的。
  • 偶尔在 XHTML 中是必需的,因为 XML 规范相当烦人地坚持将“]]>”保留在文本之外(参见“CharData”生产)。这使得总是更容易(并且无害)逃避它。
  • 对于那些感兴趣的人,hhtml_escape 的别名
【解决方案3】:

在 Ruby on Rails 3 中,HTML 默认会被转义。

对于非转义字符串使用:

<%= raw "<p>hello world!</p>" %>

【讨论】:

    【解决方案4】:

    ERB::Util.html_escape 可以在任何地方使用。在 Rails 中无需使用 require 即可使用。

    【讨论】:

    • 这其实是在下面使用CGI.escapeHTML
    • @akostadinov - 但是结果不同。例如,ERB::Util.html_escape 会将撇号变成 '而 CGI::escapeHTML 不会
    • @LouisSayers,我看不出这是怎么发生的:``` [43] pry(main)> show-source ERB::Util.html_escape From: /usr/share/ruby/ erb.rb @ line 945: Owner: # 可见性:public 行数:3 def html_escape(s) CGI.escapeHTML(s.to_s) end ```
    • @akostadinov - 嗯......再次运行,是的,它们产生了相同的输出。我发誓当我在工作中运行它时会产生不同的结果(也许是不同的 erb / cgi 版本行为?)。我得看看为什么我明天在工作中会得到不同的结果。
    【解决方案5】:

    克里斯托弗布拉德福德的答案是在任何地方使用 HTML 转义, 由于现在大多数人不使用CGI,您也可以使用Rack

    require 'rack/utils'
    Rack::Utils.escape_html('Usage: foo "bar" <baz>')
    

    【讨论】:

    • 在模型实例方法中是否有更好的方法以类似的方式转义字符串?
    • 我认为这个 Rack::Utils 只存在于 2.3 版或其他版本之前。
    • @akostadinov 我刚刚验证,截至 2021 年 11 月的今天的 rack (2.2.3) 版本,转义功能仍包含在 gem 中。
    • 是的,抱歉,我被糟糕的文档网站 UI 弄糊涂了。
    【解决方案6】:

    您可以使用h()html_escape(),但大多数人按照惯例使用h()h() 是 rails 中 html_escape() 的缩写。

    在您的控制器中:

    @stuff = "<b>Hello World!</b>"
    

    在你看来:

    <%=h @stuff %>
    

    如果您查看 HTML 源代码:您将看到输出,但实际上并未将数据加粗。 IE。它被编码为&amp;lt;b&amp;gt;Hello World!&amp;lt;/b&amp;gt;

    它将显示为&lt;b&gt;Hello World!&lt;/b&gt;

    【讨论】:

      【解决方案7】:

      不同方法的比较:

      > CGI::escapeHTML("quote ' double quotes \"")
      => "quote &#39; double quotes &quot;"
      
      > Rack::Utils.escape_html("quote ' double quotes \"")
      => "quote &#x27; double quotes &quot;"
      
      > ERB::Util.html_escape("quote ' double quotes \"")
      => "quote &#39; double quotes &quot;"
      

      我自己写了一个兼容 Rails ActiveMailer 转义:

      def escape_html(str)
        CGI.escapeHTML(str).gsub("&#39;", "'")
      end
      

      【讨论】:

        【解决方案8】:

        h() 也可用于转义引号。

        例如,我有一个使用文本字段result[r].thtitle 生成链接的视图。文本可以包含单引号。如果我没有在 confirm 方法中转义 result[r].thtitle,Javascript 将会中断:

        &lt;%= link_to_remote "#{result[r].thtitle}", :url=>{ :controller=>:resource,
        :action         =>:delete_resourced,
        :id     => result[r].id,
        :th     => thread,                                                                                                      
        :html       =>{:title=> "<= Remove"},                                                       
        :confirm    => h("#{result[r].thtitle} will be removed"),                                                   
        :method     => :delete %>
        
        &lt;a href="#" onclick="if (confirm('docs: add column &amp;apos;dummy&amp;apos; will be removed')) { new Ajax.Request('/resource/delete_resourced/837?owner=386&amp;th=511', {asynchronous:true, evalScripts:true, method:'delete', parameters:'authenticity_token=' + encodeURIComponent('ou812')}); }; return false;" title="&lt;= Remove">docs: add column 'dummy'</a>
        

        注意::html 标题声明被 Rails 神奇地转义了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-11-23
          • 1970-01-01
          • 2021-06-21
          • 2011-07-02
          • 1970-01-01
          • 2012-02-16
          • 1970-01-01
          • 2020-04-26
          相关资源
          最近更新 更多