.HTACCESS erstellt unnötige 301-Umleitungskette - Wie entferne ich sie?

Jan 12 2020

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

MrWhite Jan 12 2020 at 02:19

Sie haben zwei Hauptprobleme ....

  1. Ihre Anweisungen sind in der .htaccessDatei in der falschen Reihenfolge . Ihre HTTP-zu-HTTPS- und wwwkanonischen 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.phpum Ihre interne CMS-URL-Struktur verfügbar zu machen.
  1. Das Entfernen von .phpwird nicht tatsächlich von Ihren .htaccessAnweisungen 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 .htaccessauf demselben URL-Pfad zu HTTPS umgeleitet wird). Sie müssen oben in Ihrer .htaccessDatei Folgendes tun , um die .phpErweiterung 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 OptionsRichtlinie 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 .htaccessDatei von Hand, dann kann sie aufgeräumt werden ...

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

  2. Es sind keine Mehrfachanweisungen erforderlich RewriteEngine. Die letzte Instanz gewinnt und steuert tatsächlich die gesamte Datei.

    Mehrere <IfModule>Blöcke und RewriteEnginesind 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 .htaccessDatei 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 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 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 NCFlagge 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 mit www.Kleinbuchstaben beginnt . Mit der NCFlagge wird es nicht umleiten WwW.- obwohl dies sowieso sehr selten wäre.

  • Ich habe die unnötige Überprüfung auf HTTPS in der kanonischen Weiterleitung von www entfernt.

  • Die PTFlagge am letzten RewriteRuleist in nicht erforderlich .htaccess. In .htaccessdieser 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.