.HTACCESS erstellt eine unnötige 301-Weiterleitungskette. Wie kann ich das entfernen?

.HTACCESS erstellt eine unnötige 301-Weiterleitungskette. Wie kann ich das entfernen?

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 ...

  1. Ihre Anweisungen sind in der .htaccessDatei in der falschen Reihenfolge. Ihre HTTP-zu-HTTPS- und wwwkanonischen Weiterleitungen müssenVorIhr Front-Controller, der die URL an Ihr CMS weiterleitet. Daher die falsche externe Weiterleitung, die /index.php?url=courses/acme-course.phpIhre interne CMS-URL-Struktur offenlegt.
  1. Das Entfernen von .phpwird 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 .htaccessauf demselben URL-Pfad zu HTTPS umgeleitet wird). Sie müssen oben in Ihrer .htaccessDatei etwas wie das Folgende tun, um die .phpErweiterung 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 OptionsDirektive 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 .htaccessDatei von Hand, kann sie aufgeräumt werden …

  1. 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?

  2. Es besteht kein Bedarf für mehrere RewriteEngineRichtlinien.zuletztInstanz tatsächlichGewinntund kontrolliert die gesamte Datei.

    Mehrere <IfModule>Blöcke RewriteEnginesind 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 .htaccesswie 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 PROTOUmgebungsvariable 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 NCFlag 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 mit www.- beginnt, alles in Kleinbuchstaben. Mit dem NCFlag schlägt die Umleitung fehl WwW.- obwohl dies ohnehin sehr selten vorkommt.

  • Ich habe die unnötige Prüfung auf HTTPS bei der kanonischen WWW-Weiterleitung entfernt.

  • Das PTFlag am letzten RewriteRuleist in nicht erforderlich .htaccess. In .htaccessist 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.

verwandte Informationen