如何 HTML 编码/转义一个字符串? 是否有一个内置的?

我有一个不受信任的字符串,我希望在 HTML 页面中显示为文本。我需要将字符‘ <’和‘ &’转义为 HTML 实体。越少吵闹越好。

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

在 Ruby 或 Rails 中有内置函数吗,或者我应该自己开发一个?

160677 次浏览

The h helper method:

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

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>

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

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

For non-escaped strings use:

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

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.

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>')

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

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