
Mein Stapel:
- LAMPE
- Apache/2.4.41
Hintergrundinformation:
Ich habe vor Kurzem eine neue Website für einen Kunden gestartet. Während des Redesign-Prozesses haben wir Folgendes beschlossen:
- Wechseln Sie zu HTTPS für die gesamte Site
- Entfernen Sie die Erweiterung .php aus den URLs
- Wechseln Sie zu einem CMS
Beispiel einer ALTEN URL:
http://www.example.com/courses/acme-course.php
Beispiel für eine NEUE URL:
https://www.example.com/courses/acme-course
Mein Problem:
Wenn ein Benutzer zu einer der ALTEN URLs navigiert, erfolgt eine unnötige zusätzliche 301-Weiterleitung.
Ich verstehe nicht, warum die zusätzliche 301-Weiterleitung erstellt wird und der Benutzer nicht mit einer einzelnen 301-Weiterleitung direkt an die richtige Ziel-URL gesendet wird.
Interessante Beobachtung:
Die unnötige zusätzliche 301-Weiterleitung tritt nicht auf, wenn ich die ALTE URL mit HTTPS statt HTTP verwende.
Beispiel:
https://www.example.com/courses/acme-course.php
_
Durch die Verwendung der obigen URL wird eine einzelne 301-Weiterleitung zur richtigen Ziel-URL durchgeführt:https://www.example.com/courses/acme-course
Hier ist ein Beispiel für eine 301-Weiterleitungskette:
Ursprüngliche Anforderungs-URL:
http://www.example.com/courses/acme-course.php
1. 301-Weiterleitung (unnötig):
AUS:
http://www.example.com/courses/acme-course.php
ZU:
https://www.example.com/index.php?url=courses/acme-course.php
2. 301-Weiterleitung (korrekte endgültige Ziel-URL):
AUS:
https://www.example.com/index.php?url=courses/acme-course.php
ZU:
https://www.example.com/courses/acme-course
Mein .htaccess-Code:
# (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>
Antwort1
Sie haben zwei Hauptprobleme ...
- Ihre Anweisungen sind in der
.htaccess
Datei in der falschen Reihenfolge. Ihre HTTP-zu-HTTPS- undwww
kanonischen Weiterleitungen müssenVorIhr Front-Controller, der die URL an Ihr CMS weiterleitet. Daher die falsche externe Weiterleitung, die/index.php?url=courses/acme-course.php
Ihre interne CMS-URL-Struktur offenlegt.
Das Entfernen von
.php
wird nicht wirklich von Ihren Anweisungen durchgeführt.htaccess
?! Ich nehme an, dies muss von Ihrer Anwendungs-/CMS-Logik durchgeführt werden? Folglich wird diesstetsführt zu einer zweiten Umleitung (da.htaccess
auf demselben URL-Pfad zu HTTPS umgeleitet wird). Sie müssen oben in Ihrer.htaccess
Datei etwas wie das Folgende tun, um die.php
Erweiterung zu entfernen.RewriteRule (.+)\.php$ https://www.example.com/$1 [R=301,L]
AKTUALISIEREN:Wenn ich die Regeln/Bedingungen neu anordne, bleibt meine Platzierung von Optionen + FollowSymlinks gleich?
Es ist nicht wirklich wichtigWodie Options
Direktive kommt vor. Es ist jedoch logisch (aus Lesbarkeitsgründen), sie ganz oben zu haben. (Apache-Direktiven werden nicht unbedingt in der Reihenfolge ausgeführt, in der sie in der Konfigurationsdatei erscheinen, da jedes Modul unabhängig arbeitet.)
Vorausgesetzt, Sie codieren Ihre .htaccess
Datei von Hand, kann sie aufgeräumt werden …
Die (mehreren) Wrapper sind nicht erforderlich
<IfModule mod_rewrite.c>
. Ist mod_rewrite optional? Soll Ihre Site auf mehrere Server portiert werden, auf denen mod_rewrite nicht aktiviert ist?Es besteht kein Bedarf für mehrere
RewriteEngine
Richtlinien.zuletztInstanz tatsächlichGewinntund kontrolliert die gesamte Datei.Mehrere
<IfModule>
BlöckeRewriteEngine
sind typisch für Systeme, die automatisch durch Code bearbeitet werden und/oder so konzipiert sind, dass sie unbearbeitet auf mehreren Servern funktionieren.
Ihre Datei sollte also .htaccess
wie folgt in dieser Reihenfolge neu geschrieben werden:
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]
Zusätzliche Bemerkungen:
Die
PROTO
Umgebungsvariable enthält das angeforderte Protokoll. Mit der Reihenfolge der Weiterleitungen wird dies nun immer HTTPS sein. Der Grund für diese Variable ist, dass das CMS auf HTTP umleiten kann, wenn auf HTTP zugegriffen wird, oder auf HTTPS, wenn auf HTTPS zugegriffen wird. Wenn Sie HTTPS erzwingen, gilt dies nicht wirklich. (Obwohl diese Umgebungsvariable möglicherweise immer noch von Ihrer Anwendung verwendet wird.)Sie sollten das
NC
Flag nur selten bei einer negierten Bedingung verwenden. Deshalb habe ich es aus der Bedingung entfernt!^www\.
. Sie möchten, dass eine Umleitung erfolgt, wenn der Host nicht mitwww.
- beginnt, alles in Kleinbuchstaben. Mit demNC
Flag schlägt die Umleitung fehlWwW.
- obwohl dies ohnehin sehr selten vorkommt.Ich habe die unnötige Prüfung auf HTTPS bei der kanonischen WWW-Weiterleitung entfernt.
Das
PT
Flag am letztenRewriteRule
ist in nicht erforderlich.htaccess
. In.htaccess
ist dies das Standardverhalten (Durchleitung).Sie müssen vor dem Testen den Cache Ihres Browsers leeren, da die fehlerhaften 301-Weiterleitungen wahrscheinlich vom Browser zwischengespeichert wurden. Aus diesem Grund ist es eine gute Idee, mit 302-Weiterleitungen (temporär) zu testen.