Ruby on Rails:文字列をHTMLとしてレンダリングする方法は?


154

私が持っています

@str = "<b>Hi</b>"

そして私のerbビューでは:

<%= @str %>

ページに表示されるのは:<b>Hi</b>私が本当に欲しいのは Hiである場合です。文字列をHTMLマークアップとして「解釈」するルビーの方法は何ですか?


編集する:場合

@str = "<span class=\"classname\">hello</span>"

私の見解では

<%raw @str %>

HTMLソースコードは<span class=\"classname\">hello</span>本当に欲しいところです<span class="classname">hello</span>(二重引用符をエスケープするバックスラッシュなし)。これらの二重引用符を「エスケープ解除」するための最良の方法は何ですか?


文字列のエスケープには、%Q []構文の使用を検討することもできます。例: %Q["quotation marks"] => "\"quotation marks\"" 出典: en.wikibooks.org/wiki/Ruby_Programming/Syntax/… それが役立つかどうかわかりません。
0112 2014年

回答:


328

更新

セキュリティ上の理由から、sanitizeではなくを使用することをお勧めしますhtml_safeリンク


何が起こっているのかというと、悪意のあるコードが埋め込まれている可能性があるため、セキュリティ対策として、Railsは文字列をエスケープしています。ただし、Railsに文字列がhtml_safeであることを伝えると、そのまま渡されます。

@str = "<b>Hi</b>".html_safe
<%= @str %>

または

@str = "<b>Hi</b>"
<%= @str.html_safe %>

を使用しrawても問題はありませんが、文字列を文字列に変換してから、html_safeを呼び出すだけです。文字列があることがわかっている場合は、html_safeを直接呼び出すことをお勧めします。これにより、不要なステップがスキップされ、何が起こっているのかが明確になるためです。文字列エスケープとXSS保護の詳細は、このAsciicastにあります。


素晴らしい。1時間探してもどうすればいいのかわからなかった。ご回答有難うございます。
サリル

1
私はいつも使ってきましたraw。これについて知ってとても嬉しいです!
jmcharnes 2013

未来からハンクを与える=)
Carlos Morales


16

生を使用:

<%=raw @str >

しかし、@ jmort253が正しく言っているように、HTMLが実際にどこに属しているかを考慮してください。


こんにちは、このソリューションは機能しますが、1つの警告があります。編集された質問を参照してください
Tim

14

あなたがにしている場合にrails利用するErubisを -それを行うにはクールな方法です

<%== @str >

二重等号に注意してください。詳細については、SOの関連質問を参照してください。



7

ビジネスロジックとコンテンツを混在させています。代わりに、データをページに送信し、JQueryなどを使用して、データを必要な場所に配置することをお勧めします。

これには、すべてのHTMLが属するHTMLページにHTMLを保持できるという利点があります。これにより、Webデザイナーは、サーバー側のコードを介さずに、後でHTMLを変更できます。

または、JavaScriptを使用したくない場合は、これを試すことができます。

@str = "Hi"

<b><%= @str ></b>

少なくともこの方法で、HTMLはそれが属するHTMLページにあります。


問題は、私のアプリがマークアップが不十分なファイルを取り込み、正規表現を介して適切なHTMLマークアップに「変換」してビューに送信することです。したがって、生成されるHTMLマークアップは動的であるため、@ strを囲むことになっているタグをアプリオリに知ることはできません。モデルでない場合、この「翻訳」作業はどこで実行しますか?ビューに広範なロジックコードを含めることは想定されていませんでした。
Tim

1
それは本当に意見の問題です。新鮮なアプリを開発するときは、すべてをできるだけクリーンに保つことを好みます。しかし、多くの場合、他の人が残したものの制約内で作業しなければなりません。データソースがHTMLマークアップを返す場合は、Michael Stumのソリューションで説明されているように、「raw」の使用を検討してください。
jmort253 2011年

1
一部のコードのサポートを継承していて、そのコードに不十分な思考やデザインを示す領域がある場合、それをクリーンアップして保守しやすくすることは、実際に責​​任の一部です。見つけたままにしておくことは、最初から優れたコードである場合は問題ありませんが、作業が必要な場合はそれよりも優れたままにすることをお勧めします。私の仕事の一部は、いくつかのレガシーアプリを管理することです。私は壊れていないものを修正しないのが好きですが、それらがどのように書かれているかによって簡単に拡張することができませんでした。ほとんどの関数呼び出しを書き直さなければなりませんでしたが、今では非常に簡単に操作できます。
ティンマン

JSを使用する理由が他にない場合は、HTML補間にJavaScriptを使用しないでください。これは、JS以外のブラウザでサイトを壊します(はい、いくつかあります)。
Marnen Laibow-Koser

1
もちろん、エスケープされていないコンテンツを許可する場合、非悪のマークアップを確実にする責任はあなた次第です。
Macario 2012年

6

または、CGI.unescapeHTMLメソッドを試すこともできます。

CGI.unescapeHTML "&lt;p&gt;This is a Paragraph.&lt;/p&gt;"
=> "<p>This is a Paragraph.</p>"

0

あなたが翻訳していて、人のくだらないコード化されたファイルから必要なコードを選んでいるので、regexと組み合わせてcontent_tagを使用できますか?

APIドキュメントを盗んで、この翻訳されたコードを次のcontent_tagように補間できます。

<%= content_tag translated_tag_type.to_sym, :class => "#{translated_class}" do -%>
<%= translated_text %>
<% end -%>
# => <div class="strong">Hello world!</div>

あなたのコードを知らない、この種の考えはあなたの翻訳されたコードがあまりにも準拠していることを確実にします。


Translated_textはdiv内の実際のコンテンツだと思いますよね?つまり、例では「Hello world!」になりますか?translation_textにHTMLが多く含まれている場合、つまりネストされたdivまたはスパンがある場合はどうなりますか?content_tagを何度も呼び出す必要がありますか?
Tim

そして...申し訳ありませんが早く入力してください...ネストされた各div / spanはまだcontent_tagであり、それでも検証する必要がありますか?私たちはあなたの空想的な翻訳であなたが何をしているかを見ることができないので;-)、正規表現がhtmlの「親」にあるかどうかに関係なく、すべてのタグを探すと思います... <ul>のように... あなたはすべての李を大き​​なお尻の文字列として印刷するのではないでしょうか?それぞれが独自のcontent_tag:liになります、テキストは正しいですか?
pjammer、2011年

0

@str = "<span class=\"classname\">hello</span>" 私の見解では

<%raw @str %> HTMLソースコードは<span class=\"classname\">hello</span>、私が本当に欲しいものです<span class="classname">hello</span>(二重引用符をエスケープしていたバックスラッシュなし)。これらの二重引用符を「エスケープ解除」するための最良の方法は何ですか?

解決策:バックスラッシュでエスケープしないようにするには、一重引用符の内側に二重引用符を使用します(または二重の内側に単一引用符を使用します)。

@str = '<span class="classname">hello</span>'
<%raw @str %>

0

html_safeバージョンはRails 4でうまく機能します...

<%= "<center style=\"color: green; font-size: 1.1em\" > Administrators only </center>".html_safe if current_user.admin? %
>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.