Umleitung von nicht-www auf www Subdomain mit .htaccess

Veröffentlicht am Samstag, den 17. September 2022

Hintergrund der www-Subdomain

Ursprünglich sollte die Subdomain www. eines Unternehmens aussagen, dass sie eine Webpräsenz aufgebaut haben und diese über das Internet aufrufbar ist. Heutzutage wird in jedem gängigen Browser die Subdomain (und manchmal auch die TLD (Top-Level Domain), also z.B. .de am Ende) nahezu immer abgeschnitten, damit die URL schöner und kürzer aussieht. Klickt man dann auf die Suchleiste erscheint dann die komplette URL mitsamt Schema und Hostname. Auch bei der Eingabe der URL lässt man meistens auch das www. am Anfang weg, der Browser fügt es dann im Hintergrund trotzdem hinzu.

Tatsächlich ist es heutzutage nicht mehr so wichtig, ob man über die www-Subdomain seine Webinhalte präsentiert, oder mit der Hauptdomain arbeitet. Am Wichtigsten ist deswegen, dass man sich für eine Methode entscheidet und diese für alle Unterseiten einhält. Das ist nicht nur für den Nutzer übersichtlicher, sondern hilft auch der SEO (Search Engine Optimization).

In meinem Fall habe ich mich dazu entschieden die Website über die www-Subdomain erreichbar zu machen. Das soll den gesamten Webauftritt darstellen. Damit Anfragen nur über www.goldbergsoftware.de laufen, müssen jegliche Anfragen auf die Website, die kein www. davor besitzen, umgeleitet werden. In diesem Sinne kommen wir nun zur .htaccess Datei.

Kurzer Überblick der .htaccess Datei

Die .htaccess Datei kann unglaublich viel. Neben der Server Konfiguration ermöglicht diese Datei verzeichnisbezogene Regeln aufzustellen. Diese Datei kann also in jedem Verzeichnis des Webservers auftauchen und dort bestimmte Einstellungen verändern, die nur für dieses Verzeichnis gelten sollen. Hier sei angemerkt, dass in einem Verzeichnis alle Unterverzeichnisse durch die Datei betroffen werden. Platziert man diese Datei im Hauptordner der Site (meistens /web/), dann gilt dies für alle Unterordner. In Apache Systemen kommt .htaccess zum Einsatz.

Aber was ist denn die .htaccess Datei überhaupt? Sie ist nichts anderes, als eine Text Datei, die aufgrund des .-Präfixes typischerweise von Unix Systemen versteckt wird. Die Ausdrücke sind alle recht simpel aufgebaut und in Module aufgeteilt. Zwei dieser Module sind mod_alias und mod_rewrite. Damit werden wir die URLs auf zwei verschiedene Weisen umleiten.

Umleitung mit Redirect

Die von der Apache Canonical Hostnames Dokumentation empfohlene Vorgehensweise ist es mit Redirect zu arbeiten, da die Direktive einfacher zu verwalten ist und eben für solche einfache Umleitungen konzipiert wurde.

<If "%{HTTP_HOST} !~ /^[\w\d]+\.<DEINE-DOMAIN>\.de$/">      
Redirect permanent / https://www.<DEINE-DOMAIN>.de/
</If>
.htaccess Datei im Hauptverzeichnis

In der If-Anweisung wird geprüft, ob der Hostname nicht mit einer Subdomain anfängt. Das wird mit einer Apache Variable %{HTTP_HOST} gemacht. Lerne mehr über weitere Variablen. Der Header im HTTP-Request sieht so aus: Host: www.goldbergsoftware.de. Mit !~ wird durch den rechts stehenden regulären Ausdruck geschaut, dass der String NICHT getroffen wird. Der reguläre Ausdruck wird mit /.../ umschlossen.

Der HTTP Host soll also mit einer Subdomain beginnen ^[\w\d]+\.. Das macht man, indem der ^ Operator an erster Stelle steht. Das bedeutet, dass der String mit den nachstehenden Zeichen anfängt. In der Subdomain dürfen demnach Buchstaben und Zahlen vorkommen [\w\d] (kann man nach Belieben ändern) und davon muss mindestens eins auftreten [...]+. Um die Subdomain abzutrennen folgt ein Punkt \.. Es folgt der Domainname ohne de-Endung. Der Domainname wird von einem Punkt \. und der TLD de gefolgt, was dann das Ende des Strings mit $ kennzeichnet.

Vorstellbar wäre auch diese Bedingung, die mit einem einfachen Stringvergleich funktioniert:

"%{HTTP_HOST} != 'www.<DEINE-DOMAIN>.de'"

Falls man jedoch weitere Subdomains besitzt, die auf das gleiche Web-Verzeichnis zugreifen, würden auch diese auf www.<DEINE-DOMAIN>.de umgeleitet werden z.B. wenn man mit Subdomains statt Directories die Website durchquert und verschiedene Teile der Website somit logisch abgrenzen möchte.

Anschließend kommt die eigentliche Umleitung, die von der If-Anweisung umschlossen wird. Diese wird mit Redirect angegeben. Es folgt der Redirect Code, wobei permanent=301 ist, damit der Browser alle zukünftigen Anfragen direkt richtig losschickt. Mit / im ersten Parameter wird alles ab der Wurzel umgeleitet. Das fängt immer mit dem Root-Verzeichnis an, also werden Schema, Hostname und Port weggelassen. Die URL https://www.<DEINE-DOMAIN>.de/ gibt dann das Ziel mit www. und HTTPS-Schema an.

Umleitung mit RewriteCond und RewriteRule

Wir schreiben folgendes in eine .htaccess Datei im Hauptverzeichnis des Webservers:

RewriteEngine On
RewriteCond %{REQUEST_METHOD} GET
RewriteCond %{HTTP_HOST} ^<DEINE-DOMAIN>\.(de|com)$
RewriteRule . https://www.<DEINE-DOMAIN>.de%{REQUEST_URI} [R=permanent,L]

RewriteOptions InheritDown
.htaccess Datei im Hauptverzeichnis

Das Modul mod_rewrite aktiviert man, indem RewriteEngine on gesetzt wird. Dann folgen eine Reihe von RewriteCond, die die Umleitung erst ausführen, wenn bestimmte Bedingungen erfüllt sind.

Der Aufbau ist recht einfach gestaltet: Der zu testende String tritt an erster Stelle auf. Als zweiter Parameter folgt die Bedingung. Man kann auch bestimmte flags mit [ ] an dritter Stelle setzen, aber das soll uns nicht weiter interessieren. In unserem Fall ist der zu testende String immer eine Apache Variable. Die Bedingung ist ein regulärer Ausdruck.

In der ersten Bedingung schauen wir also, dass der Request ein GET-Request ist. Falls ein POST Request ankommt, dann ist %{REQUEST_METHOD}="POST" und "POST"!="GET". So wird dann keine Umleitung stattfinden. Man kann statt eines Strings wie GET auch mittels Attributen, wie -f für File oder -d für Directory arbeiten. Das und weitere Attribute stehen in der RewriteCond Dokumentation etwas weiter unten.

In der zweiten Bedingung wird der HTTP-Host Header geprüft. Wie mit Redirect sieht der Host-Header so aus: Host: www.goldbergsoftware.de und im regulären Ausdruck wird geprüft, ob vor der Domain keine Subdomain steht. Wie oben tritt der ^ Operator an erster Stelle. Setze deinen Domainnamen in <DEINE-DOMAIN> ein (ohne de-Endung). Der Domainname wird von einem Punkt \. und der TLD de gefolgt. In meinem Fall gibt es neben der .de-Endung auch eine .com-Endung. Damit beide Fälle abgedeckt sind, darf mit dem |-Symbol die eine oder die andere Variante stehen. Das wird in Klammern umschlossen, damit die Veroderung nur für die Endung gilt.

Abschließend kommt die eigentliche Umleitung. Der erste Parameter sagt aus wie die jetzige URL aussieht. Wie bei Redirect fängt die immer mit dem Root-Verzeichnis an, also ohne Schema, Hostname und Port. Mit regulären Ausdrücken kann man hier bestimmte Teile der URL matchen und für den zweiten Parameter speichern. Mit . wird also einfach alles getroffen bzw. uns ist die URL egal.

Im zweiten Parameter folgt schließlich die Umleitung. Mit https://www.<DEINE-DOMAIN>.de%{REQUEST_URI} wird also auf die Subdomain www. mit HTTPS-Schema umgeleitet. Die Variable %{REQUEST_UI} kann man auch in der Rewrite-Direktive verwenden. Damit erzielen wir, dass jede Anfrage auf bestimmte Seiten auch in der Umleitung weitergegeben werden und die Umleitung für den Nutzer somit das selbe Ergebnis erzielt.

An letzter Stelle kommen optionale Flags. Mit R=permanent wird der Redirect Code angegeben, wobei permanent gleichzusetzen ist wie 301. Damit wird dem Browser mitgeteilt, dass bei solchen Anfragen immer die www. verwendet werden soll. Das verbessert die Ladegeschwindigkeit der Seite, da nicht wieder umgeleitet werden muss. Es wird in der Apache Dokumentation empfohlen, wenn R verwendet wird, auch L zu verwenden. Das verhindert, dass weitere Regeln ausgewertet werden. Hier eine vollständige Liste aller Flags für RewriteRule.

Möchte man, dass diese Umleitung für alle Unterverzeichnisse gilt, die auch eine .htaccess Datei besitzen, sollte man ebenfalls RewriteOptions InheritDown angeben.

Fazit

Mit dem Rewrite-Modul kann man Umleitungen dank regulären Ausdrücken sehr einfach und kompakt gestalten. Als kleine Anmerkung sei hier gesagt, dass zuerst die RewriteRule ausgewertet wird und dann die RewriteCond. Damit kann man in der RewriteRule erstellte Variablen auch in der RewriteCond prüfen. Aber die Angabe der RewriteCond erfolgt in der Text-Datei trotzdem über die RewriteRule.

Neben dem Rewrite-Modul gibt es auch das mod_alias Modul. Es lohnt sich auch hier reinzuschauen, denn für einfache Umleitungen reicht auch die Redirect Direktive, wie in diesem Fall. Das Modul mod_alias ist für simple Fälle viel besser geeignet, da z.B. automatisch Pfadangaben nach der Umleitung weitergegeben werden können.

Ob man nun mit RewriteRule oder Redirect arbeitet, ist für diesen Fall eigentlich gleichbedeutend. Theoretisch hat Redirect eine bessere Leistung, aber die Unterschiede sind wie gesagt in diesem Fall bestimmt sehr marginal. Redirect ist einfacher zu verwalten und ich musste mir nur die Bedingung mit der Subdomain überlegen. Es kann nämlich sein, dass für gewisse Randfälle RewriteRule noch weitere RewriteCond braucht und dadurch zu unerwarteten Umleitungen führt. Ich denke aber, dass alle Fälle abgedeckt sind und der Code ähnelt anderen Lösungsansätzen von anderen Seiten.

Man kann mit RedirectMatch, einer Sonderform von Redirect, auch mit regulären Ausdrücken arbeiten. So bietet es sich in den meisten Fällen an, lieber mit Redirect zu arbeiten, als mit RewriteRule.

Weiterführende Links

Folgende Links erklären die Systematik viel verständlicher und besser, als ich das in dem Artikel gemacht habe.

Auch habe ich ein paar Links zu regulären Ausdrücken angegeben, da sie in vielen Einsatzbereichen in der Programmierung vorkommen und sehr mächtig sind. Sie erlauben eine deklarative Verarbeitung von Strings, indem angegeben wird, wie der angegebene String aufgebaut sein soll, statt einer imperativen Vorgehensweise, die z.B. über den String iteriert und mit Indexen arbeitet.