.HTACCESS erstellt unnötige 301-Umleitungskette - Wie entferne ich sie?
Mein Stapel:
- LAMPE
- Apache / 2.4.41
Hintergrundinformation:
Ich habe kürzlich eine neue Website für einen Kunden gestartet. Während des Neugestaltungsprozesses haben wir beschlossen:
- Wechseln Sie zu Sitewide HTTPS
- Entfernen Sie die Erweiterung .php aus den URLs
- Wechseln Sie zu einem CMS
Beispiel für eine ALTE URL:
http://www.example.com/courses/acme-course.php
Beispiel für eine NEUE URL:
https://www.example.com/courses/acme-course
Mein Problem:
Eine unnötige zusätzliche 301-Umleitung tritt auf, wenn ein Benutzer zu einer der ALTEN URLs navigiert.
Ich verstehe nicht, warum die zusätzliche 301-Umleitung erstellt wird und der Benutzer nicht mit einer einzigen 301-Umleitung direkt an die richtige Ziel-URL gesendet wird.
Interessante Beobachtung:
Die unnötige zusätzliche 301-Umleitung tritt nicht auf, wenn ich die ALTE URL mit HTTPS anstelle von HTTP verwende.
Beispiel:
https://www.example.com/courses/acme-course.php
_
Wenn Sie die obige URL verwenden, wird eine einzelne 301-Umleitung zur richtigen Ziel-URL von: https://www.example.com/courses/acme-course
Hier ist ein Beispiel für eine 301-Umleitungskette:
Ursprüngliche Anforderungs-URL:
http://www.example.com/courses/acme-course.php
1. 301 Weiterleitung (nicht erforderlich):
VON:
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):
VON:
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>
Antworten
Sie haben zwei Hauptprobleme ....
- Ihre Anweisungen sind in der
.htaccess
Datei in der falschen Reihenfolge . Ihre HTTP-zu-HTTPS- undwww
kanonischen Weiterleitungen müssen vor Ihrem Front-Controller erfolgen, der die URL an Ihr CMS weiterleitet. Daher die falsche externe Weiterleitung,/index.php?url=courses/acme-course.php
um Ihre interne CMS-URL-Struktur verfügbar zu machen.
Das Entfernen von
.php
wird nicht tatsächlich von Ihren.htaccess
Anweisungen durchgeführt?! Ich gehe davon aus, dass dies von Ihrer Anwendungs- / CMS-Logik durchgeführt werden muss. Folglich führt dies immer zu einer zweiten Umleitung (da.htaccess
auf demselben URL-Pfad zu HTTPS umgeleitet wird). Sie müssen oben in Ihrer.htaccess
Datei Folgendes tun , um die.php
Erweiterung zu entfernen .RewriteRule (.+)\.php$ https://www.example.com/$1 [R=301,L]
UPDATE: Wenn ich die Regeln / Bedingungen neu ordne, bleibt meine Platzierung von Optionen + FollowSymlinks gleich?
Es spielt keine Rolle, wo die Options
Richtlinie auftritt. Es ist jedoch logisch (unter dem Gesichtspunkt der Lesbarkeit), es in der Nähe der Spitze zu haben. (Apache-Anweisungen werden nicht unbedingt in der Reihenfolge ausgeführt, in der sie in der Konfigurationsdatei angezeigt werden, da jedes Modul unabhängig arbeitet.)
Angenommen, Sie codieren Ihre .htaccess
Datei von Hand, dann kann sie aufgeräumt werden ...
Die (mehreren)
<IfModule mod_rewrite.c>
Wrapper sind nicht erforderlich . Ist mod_rewrite optional? Wird Ihre Site auf mehrere Server portiert, auf denen mod_rewrite nicht aktiviert ist?Es sind keine Mehrfachanweisungen erforderlich
RewriteEngine
. Die letzte Instanz gewinnt und steuert tatsächlich die gesamte Datei.Mehrere
<IfModule>
Blöcke undRewriteEngine
sind typisch für Systeme, die automatisch per Code bearbeitet werden und / oder so ausgelegt sind, dass sie auf mehreren Servern unbearbeitet funktionieren.
Daher sollte Ihre .htaccess
Datei in der folgenden 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 beim Zugriff auf HTTP auf HTTP umleiten kann, wenn auf HTTPS zugegriffen wird, oder auf HTTPS. Wenn Sie HTTPS erzwingen, gilt dies nicht wirklich. (Obwohl diese env-Variable möglicherweise noch von Ihrer Anwendung verwendet wird.)In seltenen Fällen sollten Sie die
NC
Flagge in einem negierten Zustand verwenden. Daher habe ich es aus dem Zustand entfernt!^www\.
. Sie möchten, dass es umgeleitet wird, wenn der Host nicht mitwww.
Kleinbuchstaben beginnt . Mit derNC
Flagge wird es nicht umleitenWwW.
- obwohl dies sowieso sehr selten wäre.Ich habe die unnötige Überprüfung auf HTTPS in der kanonischen Weiterleitung von www entfernt.
Die
PT
Flagge am letztenRewriteRule
ist in nicht erforderlich.htaccess
. In.htaccess
dieser ist das Standardverhalten (Pass Through).Sie müssen Ihren Browser-Cache vor dem Testen leeren, da die fehlerhaften 301-Weiterleitungen wahrscheinlich vom Browser zwischengespeichert wurden. Aus diesem Grund ist es eine gute Idee, mit 302 (temporären) Weiterleitungen zu testen.