.HTACCESSは不必要な301リダイレクトチェーンを作成しています-削除する方法は?
私のスタック:
- ランプ
- Apache / 2.4.41
背景情報:
私は最近、クライアントのために新しいウェブサイトを立ち上げました。再設計プロセス中に、次のことを決定しました。
- サイト全体のHTTPSに切り替える
- URLから.php拡張子を削除します
- CMSに切り替えます
古いURLの例:
http://www.example.com/courses/acme-course.php
新しいURLの例:
https://www.example.com/courses/acme-course
私の問題:
ユーザーが古いURLの1つに移動すると、不要な追加の301リダイレクトが発生します。
追加の301リダイレクトが作成され、単一の301リダイレクトを使用してユーザーを正しい宛先URLに直接送信しない理由がわかりません。
興味深い観察:
HTTPの代わりにHTTPSで古いURLを使用すると、不要な追加の301リダイレクトは発生しません。
例:
https://www.example.com/courses/acme-course.php
_
上記のURLを使用すると、次の正しい宛先URLに単一の301リダイレクトが正しく実行されます。 https://www.example.com/courses/acme-course
次に、301リダイレクトチェーンの例を示します。
元のリクエストURL:
http://www.example.com/courses/acme-course.php
1ST 301リダイレクト(不要):
から:
http://www.example.com/courses/acme-course.php
に:
https://www.example.com/index.php?url=courses/acme-course.php
2ND 301リダイレクト(正しい最終宛先URL):
から:
https://www.example.com/index.php?url=courses/acme-course.php
に:
https://www.example.com/courses/acme-course
私の.htaccessコード:
# (1) General Settings
<IfModule mod_rewrite.c>
Options +FollowSymLinks
RewriteEngine On
</IfModule>
# (2) Force WWW
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=off
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{SERVER_ADDR} !=127.0.0.1
RewriteCond %{SERVER_ADDR} !=::1
RewriteRule ^ %{ENV:PROTO}://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
# (3) Force HTTPS
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
</IfModule>
# (4) URL Routing for CMS
<IfModule mod_rewrite.c>
RewriteCond %{HTTPS} =on
RewriteRule ^ - [env=proto:https]
RewriteCond %{HTTPS} !=on
RewriteRule ^ - [env=proto:http]
## Check if file/directory exists
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
## Route all other URLs to index.php/URL
RewriteRule ^(.*)$ index.php?url=$1 [PT,L,QSA]
</IfModule>
回答
あなたには2つの主要な問題があります。
.htaccess
ファイル内のディレクティブの順序が間違っています。HTTPからHTTPSおよびwww
正規リダイレクトは、URLをCMSにルーティングするフロントコントローラーの前に移動する必要があります。したがって、への誤った外部リダイレクト/index.php?url=courses/acme-course.php
-内部CMSURL構造を公開します。
の削除
.php
は、実際には.htaccess
ディレクティブによって実行されていませんか?!これはアプリケーション/ CMSロジックによって行われている必要があると思いますか?その結果、これは常に2番目のリダイレクトになります(.htaccess
同じURLパスでHTTPSにリダイレクトするため)。拡張子.htaccess
を削除するには、ファイルの先頭で次のような操作を行う必要があります.php
。RewriteRule (.+)\.php$ https://www.example.com/$1 [R=301,L]
更新:ルール/条件を並べ替えた場合、Options + FollowSymlinksの配置は同じままですか?
それは本当に問題ではありませんどこOptions
ディレクティブが発生しました。ただし、(読みやすさの観点から)上部に配置するのは論理的です。(Apacheディレクティブは、各モジュールが独立して機能するため、必ずしも構成ファイルに表示される順序で実行されるとは限りません。)
.htaccess
ファイルを手作業でコーディングしていると仮定すると、ファイルを整理することができます...
(複数の)
<IfModule mod_rewrite.c>
ラッパーは必要ありません。mod_rewriteはオプションですか?mod_rewriteが有効になっていない複数のサーバーにサイトが移植されていますか?複数の
RewriteEngine
ディレクティブは必要ありません。最後のインスタンスは、実際に勝ちとファイル全体を制御します。複数の
<IfModule>
ブロックでありRewriteEngine
、コードによって自動的に編集されるか、複数のサーバーで編集されずに機能するように設計されたシステムの典型です。
したがって、.htaccess
ファイルは次の順序で書き直す必要があります。
Options +FollowSymlinks
# Enable the rewrite engine...
RewriteEngine On
# ----------------------------------------------------------------------
# | Forcing `https://` |
# ----------------------------------------------------------------------
# Redirect to HTTPS on the "same host" (requirement for HSTS)
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L] # ---------------------------------------------------------------------- # | Forcing `www` | # ---------------------------------------------------------------------- RewriteCond %{HTTP_HOST} !^www\. RewriteCond %{SERVER_ADDR} !=127.0.0.1 RewriteCond %{SERVER_ADDR} !=::1 RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] # ---------------------------------------------------------------------- # | URL Routing for CMS | # ---------------------------------------------------------------------- # (3) RewriteCond %{HTTPS} =on RewriteRule ^ - [env=proto:https] RewriteCond %{HTTPS} !=on RewriteRule ^ - [env=proto:http] # (4) - Check if physical file exists RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # (5) - Rewrite all other URLs to index.php/URL RewriteRule (.*) index.php?url=$1 [L,QSA]
その他の注意事項:
PROTO
環境変数は、プロトコルが要求されているものは何でも含まれています。リダイレクトの順序により、これは常にHTTPSになります。この変数の理由は、HTTPにアクセスした場合はCMSがHTTPにリダイレクトできるようにするため、HTTPSにアクセスした場合はHTTPSにリダイレクトできるようにするためです。HTTPSを強制している場合、実際には適用されません。(ただし、このenv varは引き続きアプリケーションで使用される場合があります。)NC
否定された状態でフラグを使用することはめったにありません。したがって、なぜ私はそれを条件から削除したのですか!^www\.
。ホストがwww.
-すべて小文字で始まらないときにリダイレクトする必要があります。NC
フラグはリダイレクトに失敗しますWwW.
-これは非常にまれとにかくだろうが。www正規リダイレクトでのHTTPSの不要なチェックを削除しました。
PT
最後のフラグRewriteRule
はでは必要ありません.htaccess
。で.htaccess
、このデフォルトの動作は、(パススルー)です。誤った301リダイレクトがブラウザによってキャッシュされている可能性があるため、テストする前にブラウザのキャッシュをクリアする必要があります。このため、302(一時)リダイレクトでテストすることをお勧めします。