Railsでiframe内の要素のbackground-imageにbase64で読み込んだ画像を指定する
こんにちは.miです.
以前以下のページでiframeを使ってXSSを防ぐというのを書かせてもらいました.
RailsでHTMLタグを含む文字列をプレビューしつつXSSを防ぐ方法 - Aqutras Members' Blog
先日,そのiframeに背景画像を表示するというのをしました. やり方をまとめておきます.
やること
iframeの要素のbackground-imageをJSで指定します.背景画像はDBのファイルパスからファイルを読み込むといったように動的にやります.
背景画像はbase64でページと一緒に読み込みます.今回背景画像が軽かったため,別のファイルのリンクを読みに行ってアクセス数を増やすより,埋め込んだほうが軽いと判断しました.
単にCSSでやる場合
こちらのサイトで紹介されています.
以下のように,urlの部分で,data:形式:base64,base64の文字列
というように書いてやると,デコードして表示してくれます.
例えばpngだと以下のようになります.
background-image: url(data:image/png;base64,xxxxxx...);
railsで動的にファイルを読み込んでやる場合
1. ファイルをbase64で読み込む.
シンプル(?)にviewで画像読みこむよう書いています.モデルにメソッド用意すると綺麗になりそう.
- resource_obj = image_file.find(image_id) - if resource_obj && File.exists?(resource_obj.file.current_path) content_type = resource_obj.file.content_type content = Base64.strict_encode64(resource_obj.file.read
base64のエンコードはstrict_encode64
を使います.
encode64
を使った場合は60文字ごとに改行されてしまい,これをurlにセットしてもデコードしてくれません.
2. iframeにJSでセットする.
iframe id="raw-iframe" seamless=true sandbox=true srcdoc="" onLoad="contentWindow.document.body.style.backgroundImage = 'url(data:#{content_type};base64,#{content})'"
読み込まれた時に,onLoadで背景画像を書き換えます.
まとめ
iframeの背景画像をJSを使って指定するというのをやりました.
ちなみにimg
タグで画像をbase64を使って表示する場合は,encode64
でもデコードしてくれます.