web-dev-qa-db-ja.com

Apache .htaccess RewriteRuleおよびErrorDocument

_.htaccess_ファイルがあります:

_RewriteEngine On
DirectorySlash Off

RewriteCond %{REQUEST_URI}  !(\.css|\.js|\.png|\.jpg|\.mp4|\.ttf|\.eot|\.woff)$
RewriteRule ^(.*)$ ?page=$1 [NC,L,QSA]

ErrorDocument 404 /e404
ErrorDocument 403 /e404
ErrorDocument 500 /e500
_

そして、PHP関数は、要求されたURIが存在するかどうかをチェックします。URIがデータベースに存在する場合は、コンテンツを取得してページをレンダリングします。存在しない場合は、404エラーを取得します。ページのコンテンツとページのレンダリング(ここではすべて問題ありません)

問題は、_.htaccess_ファイルのRewriteCond部分内にある、_example.com/file.css_のような拡張子を持つURIを使用する場合です。この場合、ページは_example.com/e404_ (それが私が欲しいもの)にリダイレクトされます。ここでの問題は:

_example.com/e404_にリダイレクトする前に「間違ったURI」を取得する方法がわかりません。エラーページが読み込まれると、ページ内にデータベースに「間違ったURI」を挿入する関数があるためです。

2
Sinf

余談:投稿したディレクティブは、デフォルトのApacheインストールでリライトループを作成するため、質問で明らかにしていない他のディレクティブまたは別の構成がある可能性があります。とにかく、あなたはこのような問題を抱えているようには見えないので、今のところこれを無視しています。

example.com/e404にリダイレクトする前に間違ったURIを取得する方法がわかりません...

しかし、この情報を取得する必要がありますbefore「リダイレクト」? PHPでは、$_SERVER['REQUEST_URI']スーパーグローバルをチェックして、この情報(404を生成したURL)を取得できます。ただし、これにはスラッシュプレフィックスとクエリ文字列( any)、これはpage URLパラメータには含まれません。

また、用語を明確にするために、これはexample.com/e404への厳密な「リダイレクト」ではありません。 「リダイレクト」は、外部HTTPリダイレクトを意味します。 Apacheはエラードキュメントに対して内部サブリクエストを発行します(これはURLの書き換えに似ていますが、完全ではありません)。

コードの潜在的な問題の1つは、404応答がかなり遠回りの方法で提供されることです。

  1. file.cssが存在しない場合、Apacheは/e404の内部サブリクエストをトリガーします
    (これにより、処理の別のラウンドがトリガーされます...)
  2. /e404は、指定されたファイル拡張子のいずれかで終わっていないため、さらに?page=e404(おそらくindex.php?)に書き換えられます。

(不要な)2回目の書き換えのため、REDIRECT_URLREDIRECT_QUERY_STRINGなどのその他のサーバー変数(PHP $_SERVER superglobalにも渡される) )が期待どおりに設定されていません。通常、これらは「間違ったURI」(つまり、404をトリガーしたリクエストされたURL)に設定されますが、代わりにエラードキュメント自体の詳細が含まれます。

上記を1ステップで実行し、2回目の書き換えは避けてください。たとえば(index.phpがリクエストを処理するファイルであると仮定して)、エラードキュメントを目的の最終結果に設定する必要があります。

ErrorDocument 404 /index.php?page=e404

ちなみに、HTTPの "エラーステータス"(つまりe404)は、PHPの$_SERVER['REDIRECT_STATUS']スーパーグローバルで使用できるため、URLで明示的に渡す必要はありません。

RewriteRule ^(.*)$ ?page=$1 [NC,L,QSA]

index.php(登録されているDirectoryIndex)に書き換えていると思いますか? mod_dirにDirectoryIndexの追加のサブリクエストを発行させるためにフォールバックする代わりに、明示的に、書き換えるファイルをsubstitutionに含める必要があります。例えば:

RewriteRule ^(.*)$ index.php?page=$1 [QSA,L]

NCフラグはここでは不要です。)

example.com/e404にリダイレクトする前に間違ったURIを取得する方法がわかりません...

最初のクエリに対処するために、前のステップに戻ります(学術演習として)。これは、Apache 2.4.13以降で実行できます(ただし、私はあなたがneed toだとは思いません)。 Apache 2.4.13以降では、Apache式を使用して動的ErrorDocumentを作成できます。

たとえば、エラードキュメント自体のURLで404エラーの原因となったURLパスを明示的に渡すには、次のようにします。

ErrorDocument 404 /index.php?page=%{escape:%{REQUEST_URI}}&error=404

URLパラメータpageには、URLパス(スラッシュプレフィックスが含まれますが、これを除外する書き換えとは異なります)が含まれます。追加のerror URLパラメーターは、HTTPステータスを送信します(ただし、上記のように、これは厳密に必要なわけではありません)。

3
MrWhite