QUERY_STRINGを使用したルールの書き換えが機能しない

Oct 22 2020

Apacheサーバーで、mydomain.com / something /?p = valueをmydomain.com/something/?page=valueに書き換える必要があります

私は試した:

RewriteEngine On
RewriteCond %{QUERY_STRING} p=(.*)
RewriteRule ^(.*)/p=$ $1?page=%{QUERY_STRING} [L,QSA]

しかし、起きないでください、私を助けることができますか?

回答

1 MrWhite Oct 22 2020 at 14:13
RewriteCond %{QUERY_STRING} p=(.*)
RewriteRule ^(.*)/p=$ $1?page=%{QUERY_STRING} [L,QSA]

ここには多くの「エラー」があります。

  • RewriteRule パターン、すなわち。は、URLパスの一部としては発生しない^(.*)/p=$ためp=(クエリ文字列の一部であるため)、一致することはありません。RewriteRule パターン、特にクエリ文字列を除く唯一URLパスに対するマッチ。したがって、上記のURLの例では何も起こりません。

  • 置換文字列でQUERY_STRING必要なURLパラメーターの代わりにサーバー変数を使用しています。しかし、これは明らかに「クエリ文字列」全体であるため、次の形式の不正な形式のクエリ文字列を作成することになります。valueQUERY_STRINGpage=p=<value>

  • QSAフラグを使用すると、リクエストの元のクエリ文字列が、置換文字列で使用ているクエリ文字列とマージされます。したがって、これは追加されることになりますが、これは必要なものではありません。既存のクエリ文字列を置き換えようとしています。&p=<value>

  • RewriteRule ^(.*)/p=$ $1?page=-RewriteRule パターンのキャプチャグループから末尾のスラッシュを除外しているため、これにより、書き換えられたURLから末尾のスラッシュが効果的に削除されます。これはあなたの例とは異なります。

  • 内部書き換え(外部リダイレクトなし)が必要であるように見え、単一のURLパラメータの名前を「変更するだけ」です。これは、ApacheでURLを書き換えるのではなく、アプリケーションで通常解決するものです。(?)

代わりに次を試してください。

RewriteEngine On

# Internally "rewrite" the request
RewriteCond %{QUERY_STRING} ^p=([^&]*)$
RewriteRule (.*/)$ $1?page=%1 [L]

これは、スラッシュで終わるすべてのURLパスに一致します(例のとおり)。%1後方参照は、最後にマッチした中に捕獲基を指すCondPatternの、すなわち。値がpURLパラメータ。p=<value>リクエストの唯一のURLパラメータであると想定されています。


更新:それは機能しないようです...私が電話した場合、私はlocalhost/list/?p=2単に得るlocalhost/list/?p=2

はい、これは内部の「書き換え」であるため、表示されるURLは変更されません(質問で要求しているように見えます)。URLは内部的にに書き換えられlist/?page=2ます。(list/?page=2厳密には有効なエンドポイントではないポイントもあります。有効な要求を形成するには、おそらくmod_dirによってさらに書き換える必要があります。例:list/index.php?page=2?)

URLを視覚的に変更したい場合は、結局、外部の「リダイレクト」が必要になるのではないでしょうか。このためには、RewriteRule 置換文字列にスラッシュプレフィックスを含め、Rredirect)フラグを追加する必要があります。例えば:

# Externally "redirect" the request
RewriteCond %{QUERY_STRING} ^p=([^&]*)$ RewriteRule (.*/)$ /$1?page=%1 [R=302,L]

localhost/list/?p=2&?p=2以下のようにルールを変更した場合:

RewriteEngine On
RewriteCond %{QUERY_STRING} ^p=([^&]*)$
RewriteRule (.*/)$ $1&?page=%1 [L]

「要求されたURL/list/&がこのサーバーで見つかりませんでした。」なので '?' 書き直しをカット

要求した場合localhost/list/?p=2&?p=2(しかしなぜですか?)、条件が一致しないため、上記のディレクティブは何も実行しません。

なぜあなたは追加でした&RewriteRule 置換文字列?(それは意味がありませんか?)/list/&ルールが処理された場合、それは実際にフォームのURLパスになります。しかし、述べたように、あなたが述べたURLに対しては処理されませんか?