How to HTML encode/escape a string? Is there a bui

2019-01-06 12:01发布

问题:

I have an untrusted string that I want to show as text in an HTML page. I need to escape the chars '<' and '&' as HTML entities. The less fuss the better.

I'm using UTF8 and don't need other entities for accented letters.

Is there a built-in function in Ruby or Rails, or should I roll my own?

回答1:

The h helper method:

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


回答2:

Checkout the Ruby CGI class. There are methods to encode and decode HTML as well as URLs.

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


回答3:

In Ruby on Rails 3 HTML will be escaped by default.

For non-escaped strings use:

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


回答4:

ERB::Util.html_escape can be used anywhere. It is available without using require in Rails.



回答5:

An addition to Christopher Bradford's answer to use the HTML escaping anywhere, since most people don't use CGI nowadays, you can also use Rack:

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


回答6:

You can use either h() or html_escape(), but most people use h() by convention. h() is short for html_escape() in rails.

In your controller:

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

In your view:

<%=h @stuff %>

If you view the HTML source: you will see the output without actually bolding the data. I.e. it is encoded as &lt;b&gt;Hello World!&lt;/b&gt;.

It will appear an be displayed as <b>Hello World!</b>



回答7:

Comparaison of the different methods:

> 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;"

I wrote my own to be compatible with Rails ActiveMailer escaping:

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


回答8:

h() is also useful for escaping quotes.

For example, I have a view that generates a link using a text field result[r].thtitle. The text could include single quotes. If I didn't escape result[r].thtitle in the confirm method, the Javascript would break:

&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>

Note: the :html title declaration is magically escaped by Rails.