ディレクトリを指定する場合には最後にスラッシュ(/)をつけるべき

mod_rewriteを使って携帯電話とかモバイルからのアクセスをリダイレクトさせる - yuhei.kagayaで、

RewriteRule (.*) http://redirect.to/mobile/ [R=301,L]

とかやった時、ちょっと気になった。

  • HTTPステータスコード301と302はどちらも転送だけど、違いは?
  • ディレクトリにリクエストするとき、最後にスラッシュ(/)をつけた場合とつけなかった場合は?

HTTPステータスコード301と302はどちらも転送だけど、違いは?

[Studying HTTP] HTTP Status Code
こちらのサイトですべて解決しました。

そのページは移動しましたよ、この先ずっと移動先のURLでブックマーク登録よろしくね。というお引っ越し通知。
あとは、SEO的にもこの引っ越し通知はいいらしい。



また、ロボットのアクセスには、ステータスコード301によってURLが変更されたことがわかります。
Googleなら、引越し前のページにリンクしているリンク元を、引越し先に引き継ぐことができます。
ほぼ、PageRankを引き継げると言えます。


要求されたページは、今は一時的にこのURLにアクセスしてみてほしいけど、将来的には変わるから、
また同じページを見たいときは今回最初に送ってきてくれたURLでアクセスしてね、という通知。

ディレクトリにリクエストするとき、最後にスラッシュ(/)をつけた場合とつけなかった場合は?

つぎの4つの場合のRewriteRule適用を、FireFoxのアドオン、Live HTTP Headers :: Add-ons for Firefoxで監視してみた(リクエストヘッダ、レスポンスヘッダの抜粋)。

# 1:ディレクトリの最後のスラッシュ(/)を指定しない。
RewriteRule (.*) http://redirect.to/mobile [R,L]
# 2:ディレクトリの最後のスラッシュ(/)を指定する。
RewriteRule (.*) http://redirect.to/mobile/ [R,L]
# 3:ステータスコード301で返して、ディレクトリの最後のスラッシュ(/)を指定しない。
RewriteRule (.*) http://redirect.to/mobile [R=301,L]
# 4:ステータスコード301で返して、ディレクトリの最後のスラッシュ(/)を指定する。
RewriteRule (.*) http://redirect.to/mobile/ [R=301,L]

1:ディレクトリの最後のスラッシュ(/)を指定しない。

1【リクエスト】GETする
GET / HTTP/1.1
Host: redirect.from

↓

2【レスポンス】302 Foundが返ってくる
HTTP/1.x 302 Found
Date: Wed, 15 Oct 2008 05:20:20 GMT
Server: Apache
Location: http://redirect.to/mobile

↓

3【リクエスト】指定されたLocation へGETする
GET /mobile HTTP/1.1
Host: redirect.to

↓

4【レスポンス】/mobileはステータス301で移動してるので恒久的に覚えておいてと返ってくる
HTTP/1.x 301 Moved Permanently
Date: Wed, 15 Oct 2008 05:32:56 GMT
Server: Apache
Location: http://redirect.to/mobile/

↓

5【リクエスト】指定されたLocationへGETする
GET /mobile/ HTTP/1.1
Host: redirect.to

↓

6【レスポンス】リクエストは成功したよ
HTTP/1.x 200 OK
Date: Wed, 15 Oct 2008 05:32:56 GMT
Server: Apache

今回の場合、2はもうこの先ずっとURLは変わらないので301の方がベター。
3、4の通信が無駄。

2:ディレクトリの最後のスラッシュ(/)を指定する。

1【リクエスト】GETする
GET / HTTP/1.1
Host: redirect.from

↓

2【レスポンス】302 Foundが返ってくる
HTTP/1.x 302 Found
Date: Wed, 15 Oct 2008 05:22:53 GMT
Server: Apache
Location: http://redirect.to/mobile/

↓

3【リクエスト】指定されたLocation へGETする
GET /mobile/ HTTP/1.1
Host: redirect.to

↓

4【レスポンス】リクエストは成功したよ
HTTP/1.x 200 OK
Date: Wed, 15 Oct 2008 05:35:29 GMT
Server: Apache

2の時に、一時的な移動ではないので301を返した方がベター。

3:ステータスコード301で返して、ディレクトリの最後のスラッシュ(/)を指定しない。

1【リクエスト】GETする
GET / HTTP/1.1
Host: redirect.from

↓

2【レスポンス】ステータス301で移動してるので恒久的に覚えておいてと返ってくる
HTTP/1.x 301 Moved Permanently
Date: Wed, 15 Oct 2008 05:26:05 GMT
Server: Apache
Location: http://redirect.to/mobile

↓

3【リクエスト】指定されたLocationへGETする
GET /mobile HTTP/1.1
Host: redirect.to

↓

4【レスポンス】/mobileはステータス301で移動してるので恒久的に覚えておいてと返ってくる
HTTP/1.x 301 Moved Permanently
Date: Wed, 15 Oct 2008 05:38:41 GMT
Server: Apache
Location: http://redirect.to/mobile/

↓

5【リクエスト】指定されたLocationにたいし、GETする
GET /mobile/ HTTP/1.1
Host: redirect.to

↓

6【レスポンス】リクエストは成功したよ
HTTP/1.x 200 OK
Date: Wed, 15 Oct 2008 05:38:41 GMT
Server: Apache

2、3、4の通信が無駄。

4:ステータスコード301で返して、ディレクトリの最後のスラッシュ(/)を指定する。

1【リクエスト】GETする
GET / HTTP/1.1
Host: redirect.from

↓

2【レスポンス】ステータス301で移動してるので恒久的に覚えておいてと返ってくる
HTTP/1.x 301 Moved Permanently
Date: Wed, 15 Oct 2008 05:24:54 GMT
Server: Apache
Location: http://redirect.to/mobile/

↓

3【リクエスト】指定されたLocationにたいし、GETする
GET /mobile/ HTTP/1.1
Host: redirect.to

↓

4【レスポンス】リクエストは成功したよ
HTTP/1.x 200 OK
Date: Wed, 15 Oct 2008 05:37:30 GMT
Server: Apache

ということで、HTTPステータスとしても適切だし、無駄な通信がないので(ヘッダの抜粋なのでホントはもっと無駄がある)今回はこれが一番よいことがわかった。
というか、いつもURLにディレクトリを指定する場合には最後にスラッシュ(/)をつけるべきなんだねー。