サイトのリニューアルに伴ってURIが幾つか変わったためApacheの設定で対応することになった。 ブックマークされていることも考慮して対応したURIにリダイレクトするようにします。
変更点は2つ
- スマホ向けのページをレスポンシブにしたため、ULIの
/s/
を削除する - .htmlまたは.phpといった拡張子を見せないようにする
これらの設定を載せます。
環境
- httpd 2.4
ULIの/s/を削除する
移行前ではスマホからのアクセスはUser-Agent
で判定してスマホ用のページを表示していました。
URLは
- PC:
www.example.com/mypage
- スマホ:
www.example.com/s/mypage
のように/s/
を挟む仕様でした。
今回レスポンシブに対応したためどちらもPCのURLに統一します。
移行前にブクマした方向けに/s/mypage
を/mypage
と変換します。
RewriteEngine On
# URIの先頭が/s/の場合
RewriteCond %{REQUEST_URI} ^/s/.*$
RewriteRule ^(.*)/s/(.*)$ $1/$2 [L]
RewriteEngine On
はRewrite機能自体のオン・オフを制御します。
RewriteCond
はその条件に当たるURLの場合に続くRewriteRule
を適用します。
%{REQUEST_URI} ^/s/.*$はURIが
/s/`で始まる場合が条件。
URIはURLのドメイン以降の部分の文字列です。
RewriteRule
はURL変換のルール。
^(.*)/[sm]/(.*)$ $1/$2
でhttps://www.example.com/s/mypage
がhttps://www.example.com/mypage
になります。
末尾の[L]
はこれ以降の変換処理を無視するという意味です。
拡張子を見せないようにする
移行前は/login.php
と拡張子が見える状態でした。
これを/login/
としつつ/login.php
からもアクセスできるようにします。
DirectoryIndex
拡張子を見せないようにするにはDirectoryIndex
を設定します。
これは、リクエストURIがファイル名を指定せずにディレクトリだけ指定された場合にDirectoryIndex
で指定したファイルの内容をかえします。
DirectoryIndex index.php index.html index.htm
このように設定するとディレクトリ内のindex.php
が返ります。
/login/
と来た場合は/login/index.php
が返る。
index.php
がない場合はindex.html
、index.htm
と順番に探し、ない場合は404を返します。
他の拡張子のファイルも慣例的にindex
と命名します。
拡張子付きのURLを処理する
/login.php
と来た場合にはそのPHPファイルを用意していないため404となります。
そこで/login.php
を``/login`にするよう変換します。
RewriteEngine On
RewriteCond %{THE_REQUEST} ^.*\.(html|php)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)\.(html|php)(.*)$ $1/$2$4 [L]
RewriteCond
を続けるとANDの条件になる。
この例では「拡張子があり(2行目)該当するファイルとディレクトリがない(3,4行目)場合」となります。
-f
でファイルが、-d
でディレクトリが存在するかであり!
がその逆です。
RewriteRule
で拡張子を除去したURLに変換します。
/user.php?id=1
が/user?id=1
となるようクエリパラメータも考慮してあります。
まとめると
以上の処理をまとめるとこんな感じ求める動きになった。
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/[sm]/.*$
RewriteRule ^(.*)/[sm]/(.*)$ $1/$2 [R=301,L]
RewriteCond %{THE_REQUEST} ^.*/.*\.(html|php)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)\.(html|php)(.*)$ $1/$2$4 [L]
DirectoryIndex index.php index.html
スマホページも拡張子の処理が必要でしたので、一度整形したURLにリダイレクトしてから拡張子を処理するようにしています。
R=301
がステータス301でリダイレクトする設定。
mod_rewriteの参考となる記事
公式
- Apache Module mod_rewrite | httpd.apache.org
- 英語だけと公式は目を通そう
- REQUEST_URI など特別な変数やRewriteCondのパターンはこちらに説明があります。
日本語の記事
- mod_rewrite サンプル集/楽
- こちらは
RewriteRule
とRewriteCond
の関係が分かり易い
- こちらは
- RewriteRuleのフラグと、RewriteCondの変数一覧
- 末尾にある
[L]
などの記号のまとめ
- 末尾にある
あとは正規表現を自在に使えるようになりたい。
関連する書いたもの
- URLのフラグメント識別子(#以後の文字列)によってページを振り分ける方法 URLのアンカーリンクはサーバ側(Apache)まで届かない。 それをどうにか振り分けた話。