Apache Rewrite Rules が相互に破壊していますか?

Apache Rewrite Rules が相互に破壊していますか?

私にはこんなルールがあります:

RewriteCond %{REQUEST_URI} ^/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/.*$
RewriteCond %{REQUEST_URI} !^/guide/(.*)$
RewriteRule ^(.*)$ /home/neezer/public-html/domain.com/guide/$1 [L]

それ自体はうまく機能します。基本的に、私は「/guide」フォルダに保存したい多数のファイルを含む多数のディレクトリを持っていますが、SEO 上の理由から、それらを Web ルートに表示したいと考えています。

このルールは機能しますが、残念ながら元の URL (「/guide」付き) も引き続き機能します。サーバー上のファイルを実際に移動せずに、URL に「/guide」が含まれるものを、含まれないものに 301 リダイレクトしたいと考えています。

次のルールを追加してみました:

RewriteCond %{REQUEST_URI} ^/guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/.*$
RewriteRule ^guide/(.*)$ http://www.domain.com/$1 [R=301,L]

...しかし、それは私の最初のルールを完全に破っています。

私が何を間違っているのか、何か考えはありますか? この問題を解決するために他に何か必要なことがあれば、お知らせください。


編集: Matthews の提案に従って、ルールを次のように変更しました (必要な動作を反映しています):

RewriteRule ^guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ http://www.domain.com/$1-apartments/$2 [R=301,L]
RewriteRule ^(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ /home/neezer/public-html/domain.com/guide/$1-apartments/$2 [L]

ただし、ルールは依然として互いに違反していますが、今回は方法が異なります。2 番目のルールによって制御されるページ (および最初のルールによって正しくリダイレ​​クトされるページ) にアクセスしようとすると、Safari で次のエラーが発生します。

http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php」。 これは、別のページを開くようにリダイレクトされるページを開き、そのページが元のページを開くようにリダイレクトされる場合に発生する可能性があります。

助言がありますか?


追加編集:

これらのルールはループしているようです。以下は書き換えログからの抜粋です。

init rewrite engine with requested uri /manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
pass through /manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
[perdir /home/neezer/public-html/domain.com/] rewrite 'manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php' -> '/home/neezer/public-html/domain.com/guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php'

[perdir /home/neezer/public-html/domain.com/] strip document_root prefix: /home/neezer/public-html/domain.com/guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php -> /guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
[perdir /home/neezer/public-html/domain.com/] internal redirect with /guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php [INTERNAL REDIRECT]
init rewrite engine with requested uri /guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php

pass through /guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
[perdir /home/neezer/public-html/domain.com/] rewrite 'guide/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php' -> 'http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php'
[perdir /home/neezer/public-html/domain.com/] explicitly forcing redirect with http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php
[perdir /home/neezer/public-html/domain.com/] escaping http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php for redirect
[perdir /home/neezer/public-html/domain.com/] redirect to http://www.domain.com/manhattan-apartments/east-village-chinatown-lower-east-side-apartments.php [REDIRECT/301]

問題は、中間のセクション (改行で区切った) にあると思います。Apache が ( を使用して/home/neezer/...) ローカル パスに書き換えた後、ドキュメント ルートを取り除いた別の要求を発行するようです。これには当然 が含まれ/guide、最初のルールでフィルタリングされ、最終的に 2 番目のルールでフィルタリングされ、これが無限に繰り返されます。

最初のルールの後に単に停止するように指示するにはどうすればよいでしょうか? 追加しても[L]効果がないようです。

答え1

なぜ RewriteConds を使用しているのかわかりません。すべてを RewriteRules に直接配置できるように思えます。問題は、Request_URI に一致するすべてをリダイレクトしているという事実から生じているようです。RewriteRule 自体でマッチングを行うと、書き換えられたルールは次のルールと一致しなくなります。

次のようなことを試してみるとよいでしょう:

RewriteRule ^guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ http://www.domain.com/$2 [R=301]
RewriteRule ^(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ /home/neezer/public-html/domain.com/guide/$2 

あなたが達成しようとしていることをすべて理解しているわけではないので、おそらくこれらを微調整する必要があるでしょう。たとえば、以下の RewriteCond は冗長に思えたので省略しました。ガイド ディレクトリの下にあるすべてを本当に書き換えようとしている場合は、それを組み込む必要があります。

RewriteCond %{REQUEST_URI} !^/guide/(.*)$

編集
サーバー上で簡単なテストを行った後、これらのルールを機能させることはできましたが、ディレクトリごとのコンテキストでは機能しませんでした (つまり、.htaccess 内や 内ではありません<Directory></Directory>)。

私はこれをテストしていませんが、2 番目のルールで環境変数を設定し、最初のルールでそれをテストすることで、これを回避できる可能性があります。

RewriteCond %{ENV:REDIRECT} !^NO$
RewriteRule ^guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ http://www.domain.com/$2 [R=301]
RewriteRule ^(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$  [E=REDIRECT:NO]

答え2

この無限ループを回避する方法が見つからなかったので、ファイルを「neighborhoods」という新しいフォルダに移動し、次のルールを使用しました。

RewriteRule ^guide/(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ http://www.domain.com/$1-apartments/$2 [R=301,L]
RewriteRule ^(manhattan|queens|westchester|new-jersey|bronx|brooklyn)-apartments/(.*)$ /home/neezer/public-html/domain.com/neighborhoods/$1-apartments/$2 [L]

理想的とは言えません。現在、フォルダーが 2 つあるためです (ガイド外に提供している他のファイルもあります) が、SEO に関する懸念は解決されます。

関連情報