HTTPリダイレクト
Updated / Published
HTML文書の head
要素内で meta
要素のhttp-equiv
属性の値に"refresh
" を記述し、content
属性にUAが文書を読み込んでから何秒後に指定の URI文書を表示するように働きかける設定であるクライアントプルと呼ばれる技術があります。
<meta http-equiv="refresh" content="10;url=/new/">
この設定によって、別のリソース(情報資源)へと移動させるリダイレクト(ある URI から他の URI に転送させること)が可能になりますが、この方法は移動を通知するページ数が多い場合には手間がかかり、実用的ではありません。そこで、ファイルが多数あるディレクトリごと移動した場合であっても、ユーザが移動前のリソースのURI へアクセスすると自動的に移動後のリソースへと誘導することができる HTTPリダイレクトを紹介します。
HTTPリダイレクトを使う
Redirect permanent /old/ http://w3g.jp/new/
これは「old
」というディレクトリ以下のファイルにアクセスがあった場合に、自動的に「new
」というディレクトリ以下にある同じファイル名をもつファイルへと HTTPリダイレクトさせます。HTTPリダイレクトとは、ウェブサーバとUAの間で交わされるメッセージであるHTTPを用いたリダイレクトです。ウェブブラウザや検索エンジンのロボットなどの UA がウェブサーバに対してリソースをリクエスト(要求)した際のメッセージをHTTPリクエストヘッダと言い、このリクエストに対してウェブサーバが返すメッセージをHTTPレスポンスヘッダと言います。このHTTPレスポンスヘッダ内に指定のURI が別のURIに変更されたことを通知します。UA はウェブサーバからの「この URI は変更されました」というメッセージの通知を受けて、リダイレクト先のURIのウェブサーバにリクエスト(要求)しなおします。
ここでは Redirect
ディレクティブのpermanent
オプション(属性)を使っており、この設定では UA に 301 Moved Permanently
ステータスコードを返します。301 Moved Permanently
とは、そのリソースが恒久的に別の場所へ移動したことを伝え、今後は移動先のリソースへと要求するように促します。移動先の URI は絶対URI(http://
からはじまる)で記述します。
たとえば、現在アクセスしているウェブサーバの/old/a.html
のURIをリクエスト(要求)した場合、UA はサーバからファイルが移転したことの通知を受けて、http://w3g.jp/new/a.html
の URI をもつウェブサーバへと要求し、HTTP によって移動前のリソースの URI へのアクセスを自動的に移動後のリソースへとリダイレクトさせることが可能です。
正規表現を使ったHTTPリダイレクト
RedirectMatch
ディレクティブでは、通常の Redirect
ディレクティブに加えて正規表現を使った HTTPリダイレクトが可能です。たとえば、今まで HTMLファイル形式で作成していたものを、include
モジュールなどの使える PHP のファイルへと移し変えた場合を想定してみましょう。
RedirectMatch permanent (.*)\.html$ http://w3g.jp$1.php
ここでは「(.*)\.html$ http://w3g.jp$1.php
」という記述を行うことで、移転前は URI の最後が ".html
" であったファイルが要求された場合に ".html
" に代わって ".php
" の拡張子をもつファイルを要求するように設定しています。RedirectMatch
ディレクティブの後にある permanent
オプション(属性)は、そのリソースが永久的に移動したことを示すステータスを返します(オプションは次の項目にまとめています)。このように正規表現のパターンマッチ(任意の文字列に文字列のパターンをマッチさせること)を使うことでファイル名はそのままで拡張子だけを変えてHTTPリダイレクトさせたり、特定のファイルだけを HTTPリダイレクトさせることも可能です。
ただし、RedirectMatch
ディレクティブを同一サーバ内でリダイレクトさせるのに使用する際には、ディレクトリ名が重複する場合があるので注意が必要です。
RedirectMatch permanent /old/(.*) http://w3g.jp/new/old/$1
この例では、リダイレクト先の URI に転送元のディレクトリ名と同じ文字列が含まれているために無限ループ(循環)という事態に陥ります。このため同一サーバ内において HTTPリダイレクトを使用する場合は、転送先と転送元のディレクトリ名が被ることのないように注意してください。
HTTPリダイレクトとステータスコード
人間であればテキストで「このリソースは、こちらの URI へ移動しました」と記されていれば、それを理解することができますが、ウェブブラウザや検索エンジンのロボットなどを含める UA に対してリソースが移動したことを知らせるには、HTTPリダイレクトを使って通知しなければなりません。HTTPリダイレクトには、恒久的にリソースが移転したことを示す 301 Moved Permanently
ステータスコードを返す permanent
オプション以外にも、次のようなオプション(属性)があります。
Redirect
- どのステータスを返すかのオプション部分を省略した表記。デフォルトの
Redirect
ディレクティブにtemp
オプションを指定した場合と同じ302 Moved Temporarily
ステータスコードを返す。オプションをつける場合はpermanent
,temp
,seeother
,gone
の4つがある。 Redirect permanent
301 Moved Permanently
ステータスコードを返す。要求されたリソースが、永久(恒久的)に別の場所へ移動したことを伝え、今後はそちらをリクエスト(要求)するように UA へ促す。Redirect temp
Redirect
ディレクティブの初期値。302 Moved Temporarily
ステータスコードを返す。要求されたリソースが、一時的に指定の場所へ移動していることを UA に伝える。Redirect seeother
303 See Other
ステータスコードを返す。要求されたリソースが他の別のリソースで置き換えられたことを UA に伝える。Redirect gone
410 Gone
ステータスコードを返す。要求されたリソースが永久に削除されたことを UA に伝える。gone
オプションの場合は、値に URI を記述してはいけない(記述する必要がない)。
さらに、Redirect
ディレクティブのオプションを指定することなく同じステータスコードを返すディレクティブもあります。
RedirectPermanent
Redirect
ディレクティブのpermanent
オプションを指定した場合と同じ、301 Moved Permanently
ステータスコードを返す。要求されたリソースが、永久(恒久的)に別の場所へ移動したことを伝え、今後はそちらへリクエストするよう UA に促す。RedirectTemp
Redirect
ディレクティブ、またはRedirect
ディレクティブのtemp
オプションを指定した場合と同じ、302 Moved Temporarily
ステータスコードを返す。要求されたリソースが、一時的に指定の場所へ移動していることを UA に伝える。
これらはウェブサイトの管理者として是非知っておきたい知識です。Googleなどの検索エンジンのロボットにおいて移動先のリソースの URI を通知する場合には、リソースが恒久的に別の場所へ移動したことを伝え、今後は移動先のリソースへと要求するように促す 301 Moved Permanently
ステータスコードを返す方法がガイドラインで推奨されています。なぜならこの方法であれば、たとえ URI が変わっても、もとの URI に張られていたリンクなどのリンク元情報(リンクの質と量であるリンクポピュラリティも含む)を新しい URI に継承させることができるからです。
このように SEO の観点からも HTML文書などのリソースを移動させた場合には、meta
要素を使ったクライアントプルなどによるリダイレクトではなく、ウェブブラウザや検索エンジンロボットなどを含めた UA にリソースが移動したことを通知できる HTTPリダイレクトを使うようにしましょう。また、その際に検索エンジンのガイドラインで推奨されている 301 Moved Permanently
ステータスコードを返すようにしておくのが最適な設定です。302 Moved Temporarily
ステータスコードも同じようなものですが、その微妙な違いは最新版の URI が常に変化しており、移動したリソースが恒久的に固定された URI ではない場合などに適しているといえます。
mod_rewrite によるリダイレクト
Redirect
ディレクティブやRedirectMatch
ディレクティブ以外にURL書き換えエンジンのmod_rewrite
モジュールを使っても同じようにHTTPリダイレクトが実現可能です。特にmod_rewrite
モジュールは同一サーバ内のURIを正規化する場合に有効です。mod_rewrite
モジュールと各ディレクティブについての解説はここでは割愛しますが、httpまたはhttpsへの統一、wwwあり・なしの統一、index.htmlあり・なしの統一、など実用的なものにおけるmod_rewrite
モジュールを用いた301 Moved Permanently
ステータスコードを返す例を示します。ウェブサイトの管理者としては是非抑えておきたい知識です。
RewriteEngine on|off
RewriteCond テスト文字列 条件パターン
RewriteRule パターン 置換対象 [フラグ]
上記が基本形です。301 Moved Permanently
ステータスコードを返すには、フラグの部分で必ずR=301
のコードを入れる必要があるます。コードが省略されている場合は、302 Moved Temporarily
ステータスコードが返されることになり、意味が変わってくるので注意してください。
httpsスキームに統一
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
httpスキームに統一
RewriteEngine on
RewriteCond %{HTTPS} on
RewriteRule ^(.*)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
wwwサブドメインに統一
RewriteEngine on
RewriteCond %{HTTP_HOST} ^w3g\.jp$
RewriteRule ^(.*)$ http://www.w3g.jp/$1 [R=301,L]
wwwサブドメインなしに統一
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.w3g\.jp$
RewriteRule ^(.*)$ http://w3g.jp/$1 [R=301,L]
index.htmlありに統一
RewriteEngine on
RewriteRule ^$ http://%{HTTP_HOST}/index.html [R=301,L]
RewriteCond %{THE_REQUEST} ^.*/
RewriteRule ^(.*)/$ http://%{HTTP_HOST}/$1/index.html [R=301,L]
index.htmlなしに統一
RewriteEngine on
RewriteCond %{THE_REQUEST} ^(.*)/index\.html
RewriteRule ^(.*)/index\.html$ http://%{HTTP_HOST}/$1 [R=301,L]