JavaScriptを使わずに、Apacheのmod_rewrite機能でUserAgentによってSVG/PNG画像を切り替える

ブラウザに応じた画像 SVGファイル PNGファイル
fallback image tiger-icon.svg tiger-icon.png

SVGはIE8以下、Android3.0未満など未だに表示できない環境が少なくない(参考:2014年10月時点での未対応環境のシェアの調査)、そのため そうした条件であってもなんらかの手法で表示が最低限は崩れないような施策、つまりフォールバックが必要になる。

JavaScriptを使わずにできるフォールバックは様々な手法があるが

参考記事:SVGをIE等のブラウザ対応を考慮して使う方法まとめ(SVGのフォールバック画像など)|2.IDEA

反面マークアップが複雑になってしまう。その点object要素だと対応しやすいがリンクするのに結局JavaScriptが必要になるなど悩ましい課題がままある。そこでApacheのmod_rewrite機能を利用してUserAgentで判別を行い、サーバーサイドでフォールバックを行う手法ならマークアップも非常に簡潔になり、運用しやすい。

参考記事:SVG導入のためのレガシーブラウザ振り分け -Blog //ヴォルフロッシュ

@1024jpさんのこのテクニックは使い勝手もよく、便利だと思うのだがなぜかあまり利用例もブログでの紹介も見かけない……。

先の例と異なり、私は同一ディレクトリ内にSVG / PNGファイルを配置しているので .htaccess への記述をこのようにしている

#Options MultiViewsを無効に
Options -MultiViews

# mod_rewriteを有効に
RewriteEngine on
# ディレクトリが存在しない
RewriteCond %{REQUEST_FILENAME} !-d
# pngファイルは存在する場合
RewriteCond %{REQUEST_FILENAME}\.png -f
# UserAgentでの判別: IE8以下は未対応
RewriteCond %{HTTP_USER_AGENT} "MSIE [4-8]\." [NC,OR]
# Firefox がimg要素でのSVGに対応したのは4以降
RewriteCond %{HTTP_USER_AGENT} "Firefox\/[0-3]\." [NC,OR]
# Android 3.0未満は未対応
RewriteCond %{HTTP_USER_AGENT} "Android [1-2]\." [NC,OR]
# フィーチャーフォンとフルブラウザ
RewriteCond %{HTTP_USER_AGENT} (DoCoMo|UP\.Browser|SoftBank) [NC,OR]
RewriteCond %{HTTP_USER_AGENT} (NetFront\/|jig\ browser) [NC,OR]
# PlayStation3,PSP/PSP goは未対応、PlayStation4,PS Vitaは対応
RewriteCond %{HTTP_USER_AGENT} (PLAYSTATION\ (3|Portable\));) [NC,OR]
# DSi/3DS/Wiiは未対応、New 3DS,Wii Uは対応
RewriteCond %{HTTP_USER_AGENT} "Nintendo (DSi|3DS|Wii);" [NC]
# 条件に合致する場合、pngに
RewriteRule ^(.*)$ $1.png

# 上記条件以外ならばsvgに
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.svg -f
RewriteRule ^(.*)$ $1.svg

画像の配置例

<img src="http://okiru.net/by-sa/tiger-icon">
<img src="http://okiru.net/by-sa/tiger-icon.svg">
<img src="http://okiru.net/by-sa/tiger-icon.png">

拡張子をつけてSVGファイルを指定した場合はSVGファイルを、PNGファイルならPNGファイルをそのまま返す。拡張子を省略した場合にはブラウザのUserAgentに応じて判別しSVG対応の環境ならSVGファイル、未対応ならばPNGファイルを返す。


この手法のメリット

マークアップがシンプルになるのは大きい利点。img要素に限らず、CSSでの画像利用もしやすい。

また私は、はてなダイアリーを使っているのだが、こうしたレンタルブログサービスではobject要素やsvg要素の使用やJavaScriptライブラリの設置は制限されているため、そうした環境でも使える利便性がある。

そして他のフォールバック手法でしばしば問題になるのが、フォールバックされるもののSVGと代替のラスター画像ファイルの両方をダウンロードしてしまい余計な転送量が発生してしまう課題があり、その面でも優れている。

デメリットや問題点

当然、mod_rewriteを使える環境でないとダメで、.htaccessの設置も含め有償のレンタルサーバー利用者でないと難しい。(無料でできるところもあるのだろうか?)

そして大きな問題点としてはそもそもの判定基準であるUserAgentは偽装が可能なことが挙げられる。Androidにはそうした機能を持ったアプリもあり、それらの環境ではSVG未対応なのにも関わらずUserAgentに応じてSVGファイルを渡すケースも考えられる。さらには全く未知のUserAgentや、将来的には新興のブラウザが誕生する可能性も否定できない。

もちろんその都度、設定を見直し変更を行うのも良いが、この手法だけで全てをカバーするのでなく他の手法やJavaScriptも併用していくのが現実的かなー、フロントエンド・バックエンドの両面の良いところを組み合わせるといいんじゃないかなー、という結論。

(最後はふわっとした〆になった。)


これと併用してるJavaScriptについての記事も近いうちに書く……かも。


公開日:2015年02月17日

最終更新:2015年03月03日