Apache 2.4 .htaccess を変換して vhost.conf に書き換える

Apache 2.4 .htaccess を変換して vhost.conf に書き換える

以前の開発チームから受け取った Apache 2.4 構成を書き直しています。

同様の構成が約 200 行ありますが、このコードを仮想ホストに移動するにはどのような原則で変更する必要があるのか​​理解できません.htaccess

RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^(.*)$ /$1/ [R,L,NC]

仮想ホストに移動すると、理解できない場所でサイトがクラッシュします。

答え1

<VirtualHost>これらのディレクティブをコンテナ内のどこに配置するかによって異なります。

<Directory>コンテナ(つまりディレクトリ文脈)と無効化 .htaccess完全に上書きする場合は (そうでない場合はコンテナ.htaccessが上書きされます<Directory>)、ディレクティブをそのままコピーできます (<Directory>コンテナがファイルと同じディレクトリを参照していると仮定.htaccess)。

<VirtualHost>ただし、これらのディレクティブをコンテナ内(コンテナ外)に直接配置する場合<Directory>、つまり仮想ホストコンテキストで変更を加える必要があります。これは、要求がファイルシステムにマップされる前に、ディレクティブが先に処理されるためです。

あなたが投稿した指示では、次の 2 つの変更のみが必要になります。

  • 仮想ホストコンテキストでは、REQUEST_FILENAMEサーバー変数はまだ解決されていませんファイル名REQUEST_URI。これは(つまり、要求された URL)と同じです。したがって、ファイルシステム チェックは常に失敗し、条件は常に成功します。先読みを使用する必要があります。例%{LA-U:REQUEST_FILENAME}: 、または絶対ファイル名を自分で構築する必要があります。例%{DOCUMENT_ROOT}%{REQUEST_URI}: 。例:

    RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
    
  • 仮想ホストコンテキスト、一致するURLパスRewriteRule パターンはルート相対(スラッシュで始まる)です。一方、 はファイル.htaccessを含むディレクトリ.htaccess(スラッシュ プレフィックスを除く)に対する相対です。したがって、このルールを記述すると、URL パスの先頭に二重のスラッシュが出現しますが、次のように書き換える必要があります。

    RewriteRule ^/(.*)$ /$1/ [R,L]
    

    (NCここではフラグは必要ありません。)

    または、(推奨) ここではバックリファレンスを使用せず、REQUEST_URI代わりにサーバー変数を使用します (当然、これも機能します.htaccess)。例:

    RewriteRule ^ %{REQUEST_URI}/ [R,L]
    

    余談:おそらくこれも 301 永続リダイレクト (つまりR=301) である必要があります。現状では、これはデフォルトで 302 一時リダイレクトになります。ただし、意図したとおりに動作することを確認した後で、意図している場合のみ 301 に変更してください。

まとめると、次のようになります。

RewriteCond %{QUERY_STRING} ^$
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteCond %{REQUEST_URI} !^/application-module/(.*)$
RewriteCond %{REQUEST_URI} !(.*)json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/(.*)$ [NC]
RewriteRule ^/(.*)$ /$1/ [R,L]

余談:

上記は、ファイルシステムチェック(比較的高い)を最後の条件に追加し、状態リクエストがディレクティブのスラッシュで終わっていないかをチェックするRewriteRule。また、(.*)条件必須ではありません。したがって、上記はより効率的に書き直すことができます。

RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_URI} !^/application-module/
RewriteCond %{REQUEST_URI} !json$ [NC]
RewriteCond %{REQUEST_URI} !playground/local-loader/ [NC]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteRule !/$ %{REQUEST_URI}/ [R,L]

ファイル拡張子(のようなもの)を含むリクエストを除外すれば、ファイルシステムのチェックを完全に削除できる可能性がありますが、これはファイル構造によって異なります。

状態チェックする部分は!json$、実際にはファイル拡張子をチェックするべきであるように見えます.json。つまり、!\.json$(これは、上記のコメントと関連しています。全て「ファイル拡張子」を持つリクエスト。

最初状態クエリ文字列が空であることを確認するのは少し奇妙に思えますが (URL パスにスラッシュを追加するときにクエリ文字列があるかどうかは実際には問題ではないため)、これは特定の要件である必要があると思いますか?

関連情報