ワテがWindows VPSサーバーをレンタル契約して使い始めたのが2015年8月である。
その後、別のレンタルサーバー会社(つまり今使っている会社)のVPSに乗り換えた。
そのWindows VPSではASP.NETで作成したWEBサイトを幾つか運営している。
アドレスで言うと、
だ。
各種の革新的ネットサービスを提供しているにも関わらず今一つ人気が無い。
まあ、これから急速に人気が出る予感がしているので、来年早々には上位プランに変更したいと考えている。
さて、そんなワテのサイトであるが、IISでredirectやrewriteの設定が今一つ良く分からない。
何度やっても上手く行かないのだ。
今まで何度も試行錯誤したのだが、完全には解決していないのだが、今日ようやく目的の動作をさせる事が出来た。
その備忘録としてこの記事を書いた。
では、本題に入ろう。
何をどうリダイレクトしたいのか?
ワテのサイトのフォルダ構成はこんなふうになっている。
URL | フォルダの役割や目的 |
http://www.wareko.net/ | これがトップページ |
http://www.wareko.net/home/ | その実体はここ |
http://www.wareko.net/home/1.0/ | でもバージョンが増えたので |
http://www.wareko.net/home/2.0/ | それぞれのパージョン用のサブフォルダを作成した。 |
表1. ワテのサイトのフォルダ構成と意味
説明するなら、元々ワテのサイトのトップページ
の実体は
に作成していた。
サーバーのフォルダで言うと、
wwwroot/ wwwroot/home/ wwwroot/home/1.0/ wwwroot/home/2.0/
こんな感じ。
本来、例えばASP.NETでWEBサイト
を作成すると、サーバー上のフォルダ、
wwwroot/subfolder1/
にそのサイトに関するファイル、フォルダが保管される。
従って、
を作成すると、
wwwroot/
にファイルやフォルダが作成されるのだが、それだと他のフォルダ subfolder1, subfolder2 などと混じって分り辛い。
その為に、トップページ www.wareko.net に関しては、例外的にその実体を
に作成しておいた。対応するサーバーのフォルダは
wwwroot/home/
となる。
リダイレクト設定を試行錯誤
さて、
でアクセスが有った場合には
に行って欲しい。
IISをやり始めた当初のワテは良く分からなかったので、取り合えず
index.htmlをトップページ(www.wareko.net)に作成しておいて、その中で以下の命令を実行していた。
<meta http-equiv="refresh" content="0;URL=http://www.wareko.net/home/">
これでhomeフォルダにリダイレクト出来るのだ。
Meta refreshタグによるリダイレクト方法
Meta refreshと言う手法なのだが、お手軽にリダイレクト出来るので便利なのだが、調べてみるとあまりお勧めな手法では無いようだ。
まず文法上の注意としては、
contentの後にある数字で何秒後にリダイレクトするのか決められる。
<meta http-equiv="refresh" content="5;URL=http://www.wareko.net/home/">
とすると5秒後にhomeにリダイレクト出来る。
でも上の記述方法は正しいのだが、ワテの個人的な見解ではヘンテコな記述方法だと思う。
ワテだったらこんな文法にするけどなあ↓。
<meta http-equiv="refresh" content="http://www.wareko.net/home/" delay="5">
注意↑の記述方法はワテの勝手な発案なので文法違反です。
Meta refreshタグによるリダイレクトの注意点
さて、このMeta Refreshタグを利用するリダイレクトはお勧めではないらしい。
つまり、自分のサイトに大勢の人を集客するために、世の中にある多数の無料サイトなどを利用して、それらのサイトからこのMeta refreshの方法で自分のサイトにリダイレクトさせて集客を行う。
一時、そういう手法が流行った事があるらしい。でも現在ではそう言う安易は手口はGoogleなどのサーチエンジンではスパム行為と見なされて、検索のインデックスから削除されるなどの恐れがあるらしい。
所謂、グーグル八分と言う奴やな。
まあ、自分のサイトのトップページから、一つ下のサブフォルダに飛ばすくらいなら問題無いとは思うのだが。
お勧めはサーバーサイドでの301リダイレクト
で、一般にMeta Refreshタグによるリダイレクトに代わってお勧めなのはサーバーサイドで恒久的にリダイレクトするやり方だ。
俗に301リダイレクトと言う奴だ。
Apacheサーバーなら .htaccess に記述をすれば良い。
IISサーバーなら Web.Config ファイルに記述をすれば良い。
さて、問題はここからだ。
今まで
www.wareko.net/home/
にトップページの実体を保管していたのだが、最近このhome自体を改良する事が多くなった。
その結果、
www.wareko.net/home/1.0/ www.wareko.net/home/2.0/
のように、home自体が複数バージョンに分離したのだ。
それ故に
トップページからhomeにリダイレクトして来たら、さらにそこから最新版の home/2.0/ にリダイレクトする必要が生じた。
この場合にも安易にMeta Refreshタグの手法でも良いのだが、それだと芸が無い。
それにMeta Refreshタグの手法だと、何でもかんでも兎に角指定した特定のURLにリダイレクトするだけなので、例えば、
www.wareko.net/home/About.html
へ来たリクエストを
www.wareko.net/home/1.0/About.html
にリダイレクトするなどの気の利いたリダイレクトが出来ないので
www.wareko.net/home/1.0/
が表示されてしまう。
IISのweb.configファイルで301リダイレクトを行う
気の利いた細かい設定でリダイレクトさせるには、IISの場合なら web.configファイルに設定を書けば出来るのは知っている。
その記述方法が難しいのだ。
さらに、ややこしいのは
- redirect
- rewrite
の二種類があるのだ。
redirect
ワテの理解では、redirectは文字通り行先を変更する訳だが、クライアントサイドでは行先が変わった事を把握出来る。
つまり、サーバーサイドでリダイレクトを行った場合には、 クライアントに対してHTTP の「301 Moved Permanently」レスポンスコードを発行する。
それでクライアントサイドでは恒久的なリダイレクトが行われた事が分る仕組みだ。
「301リダイレクト」と言う場合の301はこのレスポンスコード301に由来している。
301リダイレクト動作の流れはこんな感じか
クライアント | http://www.wareko.net/home/ へアクセス |
サーバー | そのページは http://www.wareko.net/home/2.0/ へ移動しましたよ。(301)レスポンス送信 |
クライアント |
了解。 http://www.wareko.net/home/2.0/ へアクセス |
ちなみに
302リダイレクトは、「302 Temporary Redirect」を意味して「一時的な転送」と言う意味だ。
rewrite
一方、サーバーサイドでrewriteが行われるとそれはクライアントサイドには分からない。
へのアクセスが有った場合に、それを勝手に
に書き換えてしまう。
そしてその
の内容をあたかも
の内容としてクライアントサイドに知らせるのだ。
ワテとしては、この手法を使えば home/1.0 をアップデートして
http://www.wareko.net/home/1.0/ http://www.wareko.net/home/2.0/ http://www.wareko.net/home/3.0/
のようにバージョンが増えて行った場合でも、利用者さんから見ればいつも
でアクセスすれば良い。
その時に表示される内容は、最新版の
となるようにrewriteしたいのだ。
ところがそれが出来ない。
web.configの記述方法が分からないのだ。
IISのweb.configを編集してredirectやrewriteを試す
Windows VPSにリモートデスクトップ接続してIISマネージャーを開く。
その画面で、homeフォルダを選択すると
- HTTPリダイレクト
- URL書き換え
と言うアイコンがある。
それぞれ rediretとrewriteに対応しているのだが、その記述方法が難しい。
かなり長時間試行錯誤した結果、とりあえず以下の記述を行う事で
http://www.wareko.net/home/ へのアクセスを http://www.wareko.net/home/1.0/ へリダイレクト。
が出来るようになった。
その部分の記述をweb.configから引用。
<location path=""> <system.webServer> <httpRedirect enabled="false" destination="http://www.wareko.net/home/1.0\/" httpResponseStatus="Permanent" /> <rewrite> <rules> <rule name="wareko.net/home/ を home/1.0 へ" stopProcessing="true"> <match url="^$" /> <action type="Redirect" url="1.0/" /> </rule> </rules> </rewrite> </system.webServer> </location>
コード1.ワテの猛烈な試行錯誤でようやくリダイレクトに成功
まあ、非常に簡単な記述だとは思うのだが、ワテのような初心者にはとっても難しい。
ただしコード1の手法では
http://www.wareko.net/home/ http://www.wareko.net/home/About http://www.wareko.net/home/image.jpg
などどんなアクセスでも全て
http://www.wareko.net/home/1.0/
のトップページへリダイレクトしてしまう。
redirectでは成功したがrewriteは問題がある
コード1で無事にredirectに成功したので一件落着なのだが、ワテとしてはrewriteを実行したいのだ。
つまり、クライアントから見てワテのhomeフォルダへのアクセスは
www.wareko.net/home/
であって、
www.wareko.net/home/1.0/ www.wareko.net/home/2.0/
などの存在は見せたくない。
redirectだと1.0や2.0へ飛んで行くので、クライアントサイドにはそれらの存在が丸見え。
まあ見えても問題は無いのだが、出来れば見せたくない。
そこでコード1にあるRedirectの部分を
<action type="Redirect" url="1.0/" />
以下のようにRewriteに書き換えればいちおう設定としては正しい。
<action type="Rewrite" url="1.0/" />
ところが問題がある。
それは、ページ内にある画像のsrcの部分が、Rewrite前は
<img src="/home/1.0/myImg/0_new2p.gif">
のように、正しく画像ファイルの実体を指している。つまりサブフォルダ home/1.0 を指している。
ところが上記のrewriteを行うと、その部分が次のようになる。
<img src="/home/myImg/0_new2p.gif">
まあ、確かに 1.0 というサブフォルダの存在をクライアントサイドには見せないように動作している。
でもこれだと、
/home/myImg/0_new2p.gif
と言うファイルは存在しないので画像が表示出来ないのだ。
と言う事で、コード1のRedirectを単純にRewriteに置き換える作戦は失敗。
その後、猛烈な試行錯誤で解決した!!
web.configの記述を以下のように設定すれば、
www.wareko.net/home/
へのアクセスを、
www.wareko.net/home/1.0/
宛にリライト(rewrite)に成功した。画像も表示出来る。
<location path=""> <system.webServer> <httpRedirect enabled="false" destination="http://www.wareko.net/home/1.0\/" httpResponseStatus="Permanent" /> <rewrite> <rules> <rule name="wareko.net/home/ を home/1.0 へ" stopProcessing="true"> <match url="^(?!.*1\.0)(.*)$" /> <action type="Rewrite" url="1.0/{R:1}" /> </rule> </rules> </rewrite> </system.webServer> </location>
コード2.ワテの猛烈な試行錯誤でようやくリライトも成功
ここでは正規表現の否定先読み(?!パターン)を使っている。
やりたいことは
www.wareko.net/home/なんちゃら
に来たリクエストは、全部
www.wareko.net/home/1.0/なんちゃら
にリライトしたい。
そこで、単純に
<match url="^(.*)$" /> <action type="Rewrite" url="1.0/{R:1}" />
こんなパターンを書くと上手く行かない。
理由は言うまでも無く、この記述だと何でもかんでも
www.wareko.net/home/なんちゃら
に来たリクエストを兎に角
www.wareko.net/home/1.0/なんちゃら
に飛ばす。その結果、
www.wareko.net/home/1.0/なんちゃら
自身も
www.wareko.net/home/1.0/1.0/なんちゃら
になってしまうのだ。
そこでパスに文字列 “1.0” を含まない場合に限りこのリライトを行うようにしたのが先ほどのコード2に示した正規表現の否定先読み(?!パターン)を使った手法だ。
これで無事に
www.wareko.net/home/なんちゃら
に来たリクエストを、クライアントサイドに知らせることなく
www.wareko.net/home/1.0/なんちゃら
にリライトで飛ばせるようになったので、バージョン1.0のページを
www.wareko.net/home/
として見せる事が可能になった。
もし今後バージョンアップして 1.1 のページが出来た場合にも、
<match url="^(?!.*1\.1)(.*)$" /> <action type="Rewrite" url="1.1/{R:1}" />
のように変更すれば、利用者さんから見たらあくまで
www.wareko.net/home/
でアクセスが可能である。
なお一つ疑問がある。
先ほどの否定先読み正規表現で、最初にワテは以下に示すパターンを書いた。
<match url="^(?!.*1\.0)/(.*)$" /> <action type="Rewrite" url="1.0/{R:1}" />
つまり、フォルダを区切るスラッシュ記号を入れていた。
これでもパス名に “1.0” を含んでいない文字列
www.wareko.net/home/なんちゃら
にマッチするはずなのだが、何故かマッチしないのだ。
原因は不明。
ワテの頭がボケているだけなのかも知れない。
もし理由をご存じの方おられましたら教えてください。
まとめ
IISにおいて、特定のフォルダーに来たリクエストをそのサブフォルダーにリダイレクトする手法を説明した。
同じくサブフォルダーにリライトする方法を説明した。
これらの手法を使うと、ASP.NETを使ってサイトを作った場合に複数のバージョンが出来上がったとしても、web.configの設定を少し修正するだけで対応出来る。
リライトした場合には、利用者さんや検索エンジンから見てバージョンの数字は見えないので、SEO的にも良いのかな?分からない。
スラッシュの謎が残っているので、時間が有るときに調査したい。
以上、ワテ以外にはあまり役に立たない情報でした。
疲れた。
コメント