RewriteRuleが配置されている場所に応じて、二重のスラッシュが続くのはなぜですか?


9

次のコードを使用して、すべてのwwwリクエストをwww以外のURLに送信しています。

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

これは、私のWebサイトのルートにある.htaccessファイル内でうまく機能します。
たとえば、
www.example.com-> example.com/
www.example.com/-> example.com/
www.example.com/other_page-> example.com/other_page

ただし、これと同じコードをVirtualHost構成に移動すると、書き換えられたURLには2つの末尾スラッシュが含まれます。
www.example.com-> example.com//
www.example.com/-> example.com//
www.example.com/other_page-> example.com//other_page

書き換えルールからスラッシュを削除して修正しました。

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com$1 [R=301,L]

しかし、その理由がわかりません。誰もが理由を知っていますか?

回答:


10

私が理解しているように、.htaccessファイルでは、ルールのmod_rewriteが処理する文字列は、.htaccessファイルが置かれているディレクトリを基準にしているため、先頭に/がありません。

VirtualHostエントリでは、処理する文字列はサーバーのルートに対して絶対であり、/が含まれます。

mod_rewriteの動作に微妙な違いが生じます。

これは、同様の問題を持つ人と解決策です:

http://forum.modrewrite.com/viewtopic.php?p=56322&sid=77f72967f59200b5b5de174440234c3a

正しくエスケープしたことを覚えていれば、これはどちらのケースでも機能するはずです。

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^\/?(.*?)$ http://example.com/$1 [R=301,L]

ありがとう!少なくとも、その理由は理解できました。ただし、これは、元の質問で示したように$ 1の前にある/を単に削除するよりも、何らかの理由で優れていますか?
davekaro 2009年

1
良くも悪くも、コンテキストの違いを処理するために毎回編集する必要なく、VirtualHostの.htaccess間で交換できるブロックにすぎません。あなたの方法があなたのために働くなら、それに固執してください!:)
Neobyte 2009年

ああそうです-あなたのメソッドは.htaccessとVirtualHostの両方で動作します。それはそれをより良いIMOにします:)
davekaro

4
私は@davekaroとまったく同じ問題を抱えており、あなたの解決策を試しました。最後の行は私にとってはうまくいきませんでした。RewriteRule ^/?(.*)$ http://example.com/$1 [R=301,L]トリックをしました。
Kenny Rasschaert、2011年

2

これは、最初のスラッシュをキャプチャし(.*)てから、新しい場所でその前に別のスラッシュを適用するために発生します/$1。サーバーごとのコンテキストではなく、ディレクトリごとのコンテキストで操作する場合、mod_rewriteの動作が少し異なるため、これは以前には起こりませんでした。

オプションでスラッシュを横取りすることで、これを回避できます。さらに、余剰ドメインを持つ空のVirtualHostでRedirectMatchを使用できます。これにより、処理が少し少なくなり、見た目がきれいになります。

<VirtualHost *>
ServerName example.com
ServerAlias other.example.com
..
RedirectMatch permanent ^/?(.*) http://example.com/$1
</VirtualHost>


いいね。RedirectMatchアプローチが好きです。それは本当に私が達成したいリダイレクトなので、私はおそらくこれを使います。
davekaro 2009年

1

完全を期すために、この投稿を含めています。

Apacheのドキュメントは、この動作は非常によく発生すると「でRewriteBase」ディレクティブが存在していることの理由である理由を説明します。

.htaccessファイルに「RewriteBase」ディレクティブを含めるだけで、目的の結果が得られます。

例:

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.example\.org$ [NC]
RewriteRule ^(.*)$ http://example.com/$1 [R=301,L]

Apache 2.2 mod_rewriteのドキュメントから:

RewriteBaseディレクティブは、ディレクトリごとの書き換えのベースURLを明示的に設定します。

私の経験則では、ほとんどの場合.htaccessファイルで「RewriteBase」を使用し、Apacheの構成では使用しません。


0

私はこの問題を処理する時間がなかったので、//を/に書き換えるだけです:)

RewriteCond %{THE_REQUEST} //
RewriteRule ^(.*)$ http://domain.com [R=301,L]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.