Aqutras Members' Blog

株式会社アキュトラスのメンバーが、技術情報などを楽しく書いています。

Railsでiframe内の要素のbackground-imageにbase64で読み込んだ画像を指定する

こんにちは.miです.

以前以下のページでiframeを使ってXSSを防ぐというのを書かせてもらいました.

RailsでHTMLタグを含む文字列をプレビューしつつXSSを防ぐ方法 - Aqutras Members' Blog

先日,そのiframeに背景画像を表示するというのをしました. やり方をまとめておきます.

やること

iframeの要素のbackground-imageをJSで指定します.背景画像はDBのファイルパスからファイルを読み込むといったように動的にやります.

背景画像はbase64でページと一緒に読み込みます.今回背景画像が軽かったため,別のファイルのリンクを読みに行ってアクセス数を増やすより,埋め込んだほうが軽いと判断しました.

単にCSSでやる場合

こちらのサイトで紹介されています.

neo-shocker.com

以下のように,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でもデコードしてくれます.