HTML特殊文字のエスケープ
Rails3では<%= ~ %>を使って出力を行う場合、HTML特殊文字は自動的にエスケープされるようになりました。ここでは実際にどのようにエスケープが行われるのかを確認し、逆にエスケープを行いたくない場合にhtml_safeメソッドやrawメソッドを使う方法を解説します。
(Last modified: )
デフォルトのエスケープ処理
HTML文の中では「<」「>」「&」「"」といった文字は特別な意味を持ちます。その為、HTMLタグを含む文字列をそのまま出力してしまうと違う意味になってしまいます。その為、特別の意味を持つ文字が含まれる文字列を文字列として出力されたい場合には、特別な意味を持つ文字をエスケープした上で出力する必要があります。
現在使っているRails3では<%= ~ %>を使って出力を行う場合に自動的にエスケープ処理が行われるようになりました。つまり出力される文字列の中に例えば「<」が含まれていた場合には自動的に「<」に変換してくれます。
実際には次のように変換されます。
< --> < > --> > & --> & " --> "
では実際に簡単な例で確認してみます。「books」コントローラに次のように「show」アクションを作成します。
class BooksController < ApplicationController def show @link = '<a href="http://example.com">book store</a>' end end
インスタンス変数にHTMLタグが含まれる文字列を設定した上でテンプレートを呼び出します。テンプレートは「books」コントロールの「show」アクションから呼び出されるテンプレートとして「app/views/books/show.html.erb」ファイルを作成し、次のように記述しました。
<p> <%= @link %> </p>
インスタンス変数に含まれる値をそのまま出力しています。変数に含まれている文字列の中で特別な意味を持つ単語は自動的にエスケープされるため次の文字列が出力されることになります。
エスケープ前: <a href="http://example.com">book store</a> エスケープ後: <a href="http://example.com">book store</a>
ではアプリケーションを起動し「books」コントロールの「show」アクションを呼び出してみます。すると次のように結果がブラウザに表示されました。
このようにHTMLタグを含むような文字列を何も処理しないまま出力した場合でも自動的にエスケープ処理が行われた上で出力されます。
エスケープ処理を行わす出力する方法
自動でエスケープ処理が行われのは便利なのですがエスケープ処理を行いたくない場合もあります。そのような時はStringクラスで用意されているhtml_safeメソッドを使います。
文字列.html_safe
html_safeメソッドを使うことでこの文字列は確認済みの安全な文字列なので、特別な文字が含まれていてもそのまま出力しても大丈夫ということになり、エスケープされないまま出力されます。(実際にはhtml_safeメソッドを使うと、文字列からActiveSupport::SafeBufferクラスのオブジェクトが作成されるようです)。
では実際に試してみます。先程作成した「books」コントロールの「show」アクションから呼び出されるテンプレートである「app/views/books/show.html.erb」ファイルを次のように変更しました。
<p> <%= @link.html_safe %> </p>
アプリケーションを起動し「books」コントロールの「show」アクションを呼び出してみます。すると次のように結果がブラウザに表示されました。
エスケープ処理がされていないので、インスタンス変数に格納されていた文字列がそのまま出力されています。文字列はHTMLの<a>タグを表すものでしたので、出力された結果はリンクが表示されています。
またActionView::Helpers::OutputSafetyHelperクラスで用意されているrawメソッドを使ってもエスケープ処理を行わないようにすることができます。
raw(文字列)
rawメソッドを使うことで引数に指定された文字列はエスケープ処理がされずに出力されます。
ではこちらも試してみます。「app/views/books/show.html.erb」ファイルを次のように変更しました。
<p> <%= raw @link %> </p>
※ Rubyではメソッドを呼び出すときに括弧は省略できます。
アプリケーションを起動し「books」コントロールの「show」アクションを呼び出してみます。すると次のように結果がブラウザに表示されました。
html_safeメソッドを使った場合と同じくエスケープ処理がされていないので、インスタンス変数に格納されていた文字列がそのまま出力されています。html_safeメソッドでもrawメソッドでもこのような使い方をする場合は同じ結果となります。
( Written by Tatsuo Ikura )
著者 / TATSUO IKURA
これから IT 関連の知識を学ばれる方を対象に、色々な言語でのプログラミング方法や関連する技術、開発環境構築などに関する解説サイトを運営しています。