適当プログラマー

私のサイトはXHTML1.1。

アイキャッチ

.htaccessを使ってapplication/xhtml+xmlとtext/htmlに振り分ける。

XHTMLのメディア型にはapplication/xhtml+xmlが推奨されているが、現在ブラウザシェアの過半数を握るInternet Explorerがapplication/xhtml+xmlに対応していない。

そこで、私がググりながら地道に作ったのが、ブラウザによってメディア型を.htaccessで振り分ける方法だ。

とりあえず私が実際に使っているものがこちら。

RewriteEngine on
DirectoryIndex index.xhtml index.php index.html

AddType "application/xhtml+xml; charset=utf-8" .xhtml

RewriteCond %{HTTP_ACCEPT} !application/xhtml\+xml
RewriteCond %{REQUEST_FILENAME} \.xhtml
RewriteRule .* - "[T=text/html; charset=utf-8]" [L]

ErrorDocument 404 /error/file_not_found.xhtml

*以下に解説する事は、素人が素人なりに理解したことです。正確な情報はApache module mod_rewriteなどを参照してください。また、上記の.htaccessファイルはInternet Explorer7で正常に動作することを確認しておりますが、Internet Explorer6では動作するかどうか確認しておりません。あらかじめご了承ください。

というわけで、早速解説。まず一行目。RewriteEngineをonにしています。これにより、下記のRewriteCond及びRewriteRuleが使えるようになります。逆に、offにすると、Rewrite機能が一切動作しなくなります。

DirectoryIndexは、今回のテーマと関係ない個人的な事に使っています。私の場合、XHTMLファイルの拡張子を全て.xhtmlにしています。しかし、標準的なサーバーではindex.xhtmlをトップページにした場合、indexファイル名を省略したアドレスではindex.xhtmlを表示してくれません(私のサイトにhttp://www.garunimo.com/というアドレスでアクセスしてもindex.xhtmlが表示されない)。

しかし、DirectoryIndexを使えば、index.xhtmlファイル名を省略しても、index.xhtmlファイルにアクセス出来るようにすることができます。優先順位は左側に書いた物の方が高くなります。私の例では、http://www.garunimo.com/にアクセスした場合、まずindex.xhtmlを表示しようとし、それが無ければindex.phpを表示しようとし、それもなければindex.htmlファイルを表示することになります。

次がAddTypeです。この指定により、とりあえず拡張子が.xhtmlである全てのファイルのメディアタイプをapplication/xhtml+xml(文字コードをutf-8)に指定しています。一番最後の.xhtmlを.htmlに直せば.htmlという拡張子のファイルにこの命令が適用されることになります。

次に、RewriteCondの説明です。RewriteCondによりルールの条件を定義することが出来ます。今回定義するルールは「もしapplication/xhtml+xmlを使えないブラウザであれば(かつ、対象のファイルの拡張子が.xhtmlであれば)」というルールです。

RewriteCondで定義したルールにもし当てはまれば、RewriteRuleを適用することになります。RewriteRuleには「メディアタイプをtext/htmlにする」という定義をします。

ブラウザがapplication/xhtml+xmlを扱えるかどうかはブラウザのHTTPヘッダ情報のHTTP_ACCEPTを確認すれば分かります。HTTP_ACCEPTにはそのブラウザが扱うことのできるメディアタイプが全て書かれており、もしその中にapplication/xhtml+xmlが無ければそのブラウザはapplication/xhtml+xmlを扱えないことになります。

今回の.htaccessを見ていただくと、%{HTTP_ACCEPT}で、HTTP_ACCEPTの情報を取り出しています。!application/xhtml\+xmlで、「application/xhtml+xmlがもし無ければ」という意味になります。最初の!(ビックリマーク)が否定の意味です。また、正規表現によって情報を指定するので「!application/xhtml+xml」と書くと「+」が特別な意味を持ってしまう為「+」の前に「\」を書きエスケープをしなければなりません。

条件の二つ目には「(かつ)拡張子が.xhtmlであれば」というルールを書きます。RewriteCondは複数並べることが出来、暗黙のAND(かつ)になります。

%{REQUEST_FILENAME}には、リクエストされたファイルの名前が入ります。その後、拡張子を指定しています。私の場合は.xhtmlを指定していますが、htmlの場合は\.htmlという指定になるかと思います。.「ピリオド」も正規表現において特別な意味を持ってしまうため、\を前においてエスケープします。

最後にRewriteCondに当てはまった物に対してRewriteRuleを適用させます。一つ目の.*はURLに対しての正規表現です。条件に当てはまった全てのアドレスのメディアタイプをtext/htmlにしたいので、正規表現で(条件に当てはまった)全てのファイル(名)を指定しています。

その次の-にご注目。これも書き損じでは無くて立派に意味があります。これは、「(アドレスの)置換を行わない」という意味です。一般的にはRewriteRuleはアドレスの転送などへ使われるので、ここ(第二引数)には変換後のファイル名(アドレス名)を記入するのですが、今回はメディア型を書き換えたいだけで、ファイル名その物は書き換える必要が無いので-を使います。

次の"[T=text/html; charset=utf-8]"が実際にメディアタイプを書き換えているところです。

最後の[L]は、「今回RewriteRuleで行った変換に対してこれ以上の変換を行わない」という意味です。一つの.htaccessに複数回のRewriteCond及びRewriteRuleが書けるため、もし仮に後日.htaccessを書き換えて別のRewriteCondとRewriteRuleを付け足した場合、意図せず今回行った変換に更に上書きで変換を行ってしまう可能性があります。それを[L]で防いでいるというわけです。ただ、今回の例ではメディアタイプを書き換える命令しか行っていないため、[L]が無くても、特に問題なく動きます。

これでメディアタイプを書き換える方法の解説は終了です。.htaccessは、あるディレクトリに入れれば、そのディレクトリ以下のディレクトリにも全て.htaccessが適用されます。私はこれをトップディレクトリにいれています。

ちなみに、最後のErrorDocument 404 〜は今回のテーマとは関係ない、ファイルが存在しない「404 FILE NOT FOUND」の時のエラーページを自分で作ったエラーページに変えるための命令です。

今回の例では「404エラーの時は/error/file_not_found.xhtmlファイルを表示せよ」という命令になります。

以上で解説は終了しますが、あくまで素人が頑張って自分なりに理解したことを説明しただけなので正しい情報はApacheのドキュメントなどを参照してください。

と、ここまで解説して一応ググってみたらこんな記事を見つけました。application/xhtml+xml と mod_rewrite

が、私の環境ではLA-F:をつけなくてもきちんと動作しています。恐らくDirectoryIndex index.xhtml index.php index.htmlの部分が思わぬ副作用をもたらして、http://www.garunimo.com/index.xhtmlだけでなく、http://www.garunimo.com/でも上手く動作しているようです。というわけで、もしあなたのトップページがindex.htmlなら、私のDirectoryIndex index.xhtml index.php index.htmlの部分をDirectoryIndex index.htmlに直して、後は解説どおりにすれば上手く動作すると思います。

このエントリーをはてなブックマークに追加