Don't escape html in ruby on rails

后端 未结 2 1473
有刺的猬
有刺的猬 2020-12-08 06:15

rails 3 seems to escape everything, including html. I have tried using raw() but it still escapes html. Is there a workaround? This is my helper that I am using (/helpers

相关标签:
2条回答
  • 2020-12-08 06:54

    I ran into this same thing and discovered a safer solution than using html_safe, especially once you introduce strings which are dynamic.

    First, the updated code:

    def good_time(long_message1, long_message2, status = true)
      html = "".html_safe
      html << "Status is #{status}, "
      if status
        html << long_message1
      else
        html << long_message2
      end
      html
    end
    
    <%= good_time(true) %>
    

    This escapes long_message content if it is unsafe, but leaves it unescaped if it is safe.

    This allows "long message for success & such." to display properly, but also escapes "malicious message <script>alert('foo')</script>".

    The explanation boils down to this -- 'foo'.html_safe returns an ActiveSupport::SafeBuffer which acts like a String in every way except one: When you append a String to a SafeBuffer (by calling + or <<), that other String is HTML-escaped before it is appended to the SafeBuffer. When you append another SafeBuffer to a SafeBuffer, no escaping will occur. Rails is rendering all of your views under the hood using SafeBuffers, so the updated method above ends up providing Rails with a SafeBuffer that we've controlled to perform escaping on the long_message "as-needed" rather than "always".

    Now, the credit for this answer goes entirely to Henning Koch, and is explained in far more detail at Everything you know about html_safe is wrong -- my recap above attempts only to provide the essence of the explanation in the event that this link ever dies.

    0 讨论(0)
  • 2020-12-08 07:09

    You can use .html_safe like this:

    def good_time(status = true)
      if status
        "Status is true, with a long message attached...".html_safe
      else
        "Status is false, with another long message".html_safe
      end
    end
    
    <%= good_time(true) %>
    
    0 讨论(0)
提交回复
热议问题