permalink

1

Automatische Weiterleitung

Wenn sich die Adresse einer Res­source ändert, sollte diese wei­ter­hin unter dem alten URI erreich­bar sein. Dies errei­chen Sie mit­tels einer Wei­ter­lei­tung. Die­ser Arti­kel dis­ku­tiert meh­rere Mög­lich­kei­ten mit dem Schwer­punkt ser­ver­sei­tige Weiterleitung.

Anmer­kun­gen: Den Abschnitt »Wei­ter­lei­tung mit PHP« habe ich mit freund­li­cher Geneh­mi­gung von Jens Becker über­nom­men. Jens Becker ist Java-Entwickler und Experte für ser­ver­sei­tige Pro­gram­mie­rung mit PHP und MySQL.

Mitt­ler­weile läuft meine Web­site auf dem Infor­ma­ti­ons­sys­tem onion​.net. Die Aus­sa­gen zur tech­ni­schen Rea­li­sie­rung mit­tels PHP sind daher nicht mehr aktuell.

Zum Sei­ten­an­fang

Warum wei­ter­lei­ten?

Die Ent­wick­lung einer Web­site beginnt mit dem Ent­wurf der Infor­ma­ti­ons­ar­chi­tek­tur und Daten­or­ga­ni­sa­tion. Sie stel­len Mate­rial zusam­men, unter­tei­len es in Infor­ma­ti­ons­ein­hei­ten und über­le­gen sich, wie Sie diese auf der Web­site prä­sen­tie­ren sollen:

  • Wel­che Tech­no­lo­gien ste­hen zur Ver­fü­gung und wel­chen Ein­schrän­kun­gen unter­lie­gen sie?
  • Wel­che Ver­zeich­nisse und Unter­ver­zeich­nisse benö­ti­gen Sie, wel­che Res­sour­cen beinhal­ten diese?
  • Wie wer­den Res­sour­cen aus­ge­lie­fert und über wel­che URIs sind sie adressierbar?

Sobald Sie die Pla­nung einer Web­site abge­schlos­sen und das Kon­zept aus­rei­chend geprüft haben, kön­nen Sie mit der Rea­li­sie­rung der Web­site begin­nen, diese wie­derum meh­re­ren Eva­lua­ti­ons­durch­läu­fen durch­zie­hen, Craw­ler ein­set­zen, wel­che die Kon­sis­tenz der Web­site über­prü­fen, und die fer­tige Site schließ­lich publi­zie­ren. Nun gibt es rein theo­re­tisch kei­nen Grund mehr, den Auf­bau der Web­site zu ver­än­dern und Res­sour­cen zu ver­schie­ben oder zu löschen – in der Pra­xis gibt es lei­der einige davon:

  • Doku­mente sind ver­al­tet und sol­len gelöscht oder in ein Archiv ver­scho­ben werden.
  • Es wird eine andere Tech­no­lo­gie ein­ge­setzt, bei­spiels­weise ein ande­res Content-Management-System, wodurch die Infor­ma­ti­ons­ar­chi­tek­tur sich ändert und der URI oder Teile davon anders aussehen.
  • Im Rah­men eines Relaunchs der Web­site wer­den die Inhalte kom­plett umstruk­tu­riert, bei­spiels­weise an eine ver­än­derte Unter­neh­mens­struk­tur angepasst.
  • Ein Anbie­ter muss seine gesamte Web­site vom Netz neh­men, zum Bei­spiel Inhalte der Web­site einer Firma, die Pleite gegan­gen ist oder auf­ge­kauft wurde.

Alle diese Maß­nah­men füh­ren dazu, dass Res­sour­cen über­haupt nicht mehr oder nicht unter der ursprüng­li­chen Adresse erreich­bar sind, unter die sie in Tref­fer­lis­ten von Such­ma­schi­nen, Lese­zei­chen oder auf ande­ren Web­sites ver­linkt sind. Das Ergeb­nis sind Feh­ler der Art 404 (Not Found) und frus­trierte Besu­cher, wel­che die gesuchte Infor­ma­tion nicht sofort erhal­ten, son­dern sie erst suchen müs­sen – wenn sie sich über­haupt darum bemü­hen und nicht ver­är­gert für immer von dan­nen zie­hen. Gelan­gen Besu­cher über eine Such­ma­schine auf eine Web­site, wer­den sie kaum den Auf­wand betrei­ben, die Site nach der gewünsch­ten Res­source zu durch­fors­ten, son­dern wäh­len statt­des­sen ein­fach den nächs­ten Ein­trag in der Trefferliste.

Wenn sich der URI einer Res­source ändert, aus wel­chen Grün­den auch immer, sollte diese wei­ter­hin unter dem alten URI erreich­bar sein. Dies errei­chen Sie über eine Weiterleitung.

Zum Sei­ten­an­fang

Ser­ver­sei­tige Weiterleitung

Ser­ver­sei­tige Wei­ter­lei­tung bie­tet Ihnen zwei Vorteile:

  1. Der Ser­ver lei­tet nicht nur wei­ter, son­dern sen­det auch einen ent­spre­chen­den Sta­tus­code. Dadurch wird der Cli­ent, der die Res­source ange­for­dert hat, über die Ände­rung infor­miert. Such­ma­schi­nen aktua­li­sie­ren ihren Index ent­spre­chend und zei­gen in der Folge den neuen URI an.
  2. Der Besu­cher bekommt von der Wei­ter­lei­tung nichts mit, son­dern ihm wird unmit­tel­bar die ange­for­derte Res­source unter der neuen Adresse angezeigt.

<?php include("../../includes/htaccess.inc.php"); ?>

Die Redirect-Direk­tive des Apa­che Webservers

Der Web­ser­ver Apa­che ermög­licht ser­ver­sei­tige Wei­ter­lei­tun­gen durch die Direk­tive Redirect. Andere Web­ser­ver bie­ten ähnli­che Mög­lich­kei­ten. Die Redirect-Direk­tive bil­det einen alten URI auf einen neuen ab. Der neue URI wird an den Cli­ent zurück­ge­lie­fert, der dar­auf­hin ver­su­chen wird, das Doku­ment unter der neuen Adresse abzu­ru­fen. Redirect-Direk­ti­ven notie­ren Sie in der Kon­fi­gu­ra­ti­ons­da­tei httpd.conf oder in Zugriffs­kon­troll­da­teien (htaccess-Dateien). Die Syn­tax ist wie folgt:

Redirect [<Status>] <Pfad> <URI>

Das Sta­tus­ar­gu­ment ist optio­nal und wird im wei­te­ren Ver­lauf die­ses Abschnitts erklärt. Der Pfad ist der Teil des alten URI nach dem Server-Namen. Lau­tete der alte URI http://www.example.com/foo/bar, müs­sen Sie als Pfad /foo/bar notie­ren. Alle Anfra­gen für Res­sour­cen, die mit die­sem Pfad begin­nen, wer­den mit einem ent­spre­chen­den Umlei­tungs­sta­tus auf den neuen URI ver­wie­sen. Fol­gende Wei­ter­lei­tung lei­tet alle Anfra­gen an /foo/ an http://www.example.com/bar/ weiter.

Redirect /foo/ http://www.example.com/bar/

Wird kein Sta­tus­ar­gu­ment über­ge­ben, wird eine tem­po­räre Umlei­tung ange­nom­men (Sta­tus 302, Found). Dadurch wird dem Cli­ent mit­ge­teilt, dass die Res­source ledig­lich vor­über­ge­hend unter der neuen Adresse erreich­bar ist. Sie kön­nen fol­gende Sta­tus­ar­gu­mente angeben:

permanent
Der Ser­ver sen­det Sta­tus 301 (Moved Per­man­ently), um anzu­zei­gen, dass die Res­source für immer unter dem neuen URI erreich­bar ist.
temp
Der Ser­ver gibt den Sta­tus 302 (Found) zurück. Dies ist die Stan­dard­ein­stel­lung und ent­spricht dem Ver­hal­ten, wenn Sie kein Sta­tus­ar­gu­ment angeben.
seeother
Der Ser­ver gibt den Sta­tus 303 (See Other) zurück. Dadurch kön­nen Sie deut­lich machen, dass die ursprüng­li­che Res­source ersetzt wurde.
gone
Der Ser­ver sen­det den Sta­tus 410 (Gone). Die ange­for­derte Res­source ist auf dem Ser­ver nicht mehr erreich­bar und es ist auch kein neuer URI bekannt. Such­ma­schi­nen, die den Sta­tus­code 410 zurück­er­hal­ten, soll­ten die Res­source aus ihrem Index entfernen.

Dar­über hin­aus kön­nen Sie belie­bige andere Sta­tus­codes zurück­ge­ben, indem Sie ihren nume­ri­schen Wert als Sta­tus­ar­gu­ment ange­ben. Alle Sta­tus­codes fin­den Sie in der HTTP-Spe­zi­fi­ka­tion in Abschnitt 10. Wenn der Sta­tus­code im Bereich 300 bis 399 liegt, müs­sen Sie eine Wei­ter­lei­tungs­adresse ange­ben. Außer­dem muss das Sta­tus­ar­gu­ment einem dem Apa­che bekann­ten Code entsprechen.

Neben der Direk­tive Redirect gibt es die Direk­ti­ven RedirectPermanent und RedirectTemp, die ledig­lich andere Schreib­wei­sen für die Redirect-Direk­tive mit dem ent­spre­chen­den Sta­tus­ar­gu­ment dar­stel­len, und die Direk­tive RedirectMatch, bei der Sie mit regu­lä­ren Aus­drü­cken arbei­ten kön­nen. Das fol­gende Bei­spiel ersetzt /foo/ in allen Anfra­gen durch /bar/. Würde ein Benut­zer bei­spiels­weise http://www.example.com/foo/document anfra­gen, würde der Web­ser­ver nach http://www.example.com/bar/document weiterleiten.

RedirectMatch permanent /foo/([^\.]+) /bar/$1

Das Apache-Modul mod_rewrite

Ein wei­te­res, sehr mäch­ti­ges Werk­zeug, das Sie unter ande­rem zur Wei­ter­lei­tung von einem URI zu einem ande­ren nut­zen kön­nen, bie­tet mod_rewrite. Dabei han­delt es sich um ein Apache-Modul für die URI-Mani­pu­la­tion. Mit der Rewri­teEn­gine des Apache-Webservers ist es mög­lich, den ange­for­der­ten URI anhand von Regeln umzu­schrei­ben und somit vir­tu­elle URIs zu erzeu­gen, die auf tat­säch­lich vor­han­dene ver­wei­sen. Basie­rend auf einem Par­ser für regu­läre Aus­drü­cke kann der ange­for­derte URI mani­pu­liert wer­den. mod_rewrite ist sehr kom­plex und bie­tet der­art viele Mög­lich­kei­ten, dass man ein gan­zes Buch dar­über schrei­ben könnte. Um Brian Beh­len­dorf, ein Mit­glied der Apa­che Group, zu zitieren:

»The great thing about mod_rewrite is it gives you all the con­fi­gu­ra­bi­lity and fle­xi­bi­lity of Send­mail. The down­side to mod_rewrite is that it gives you all the con­fi­gu­ra­bi­lity and fle­xi­bi­lity of Sendmail.«

Ich beschränke mich im Rah­men die­ses Arti­kels nur auf eine kleine Ein­füh­rung und zwei Anwen­dungs­bei­spiele. Wei­tere Infor­ma­tio­nen erhal­ten Sie in den Apache-Manuals.

Um mod_rewrite zu nut­zen, müs­sen Sie Ihre Zugriffs­kon­troll­da­tei zunächst um fol­gende Zei­len erweitern:

RewriteEngine on
RewriteBase /
Options +FollowSymlinks

Die erste der drei Zei­len star­tet das Modul. RewriteBase gibt den Basis-URI an, in die­sem Fall das Root-Verzeichnis der jewei­li­gen Domain. FollowSymlinks bewirkt, dass bei Wei­ter­lei­tun­gen via mod_rewrite den sym­bo­li­schen Links auf dem Web­ser­ver auch gefolgt wer­den kann. Anschlie­ßend fol­gen die Such­mus­ter. Dazu ver­wen­den Sie die Direk­tive RewriteRule. Sie hat fol­gende Syntax:

RewriteRule <Muster> <Ersatz>

Als Bei­spiel ein recht sim­ples Such­mus­ter: Ein Nut­zer wird bei Auf­ruf der Res­source /foo an die Res­source /bar wei­ter­ge­lei­tet, ohne dass er davon etwas merkt; der URI, der in der Adress­zeile des Brow­sers ange­zeigt wird, bleibt unverändert.

RewriteRule ^foo$ /bar

Die Zei­chen ^ und $ stel­len Anker dar, die Anfang und Ende des Mus­ters aus­ge­hend vom Basis-URI markieren.

Zuge­ge­ben, das Bei­spiel ist nicht son­der­lich auf­re­gend. Span­nen­der wird es, wenn Sie mit regu­lä­ren Aus­drü­cken arbei­ten. Dazu ein Bei­spiel aus der Pra­xis: Ich habe meine deut­sche Über­set­zung Bert Bos’ lesens­wer­ten Essays »What is a good stan­dard?« schein­bar in meh­rere Doku­mente unter­teilt, um die Lade­zei­ten gering zu hal­ten. Zusätz­lich wird es in einem Doku­ment kom­plett ange­bo­ten. Die Ein­tei­lung in meh­rere Doku­mente fin­det aller­dings nur vir­tu­ell statt. Es han­delt sich in Wirk­lich­keit um eine ein­zige PHP-Datei mit diver­sen if-Abfra­gen fol­gen­der Art:

<?php
if( isset($_GET["show"]) ) {
  if($_GET["show"] == "wartbarkeit" ||
    $_ GET["show"] == "essay") {
    // Ausgabe
  }
}
?>

Es wird ein Para­me­ter show nach sei­nem Wert abge­fragt. Um den Abschnitt »Wart­bar­keit« anzu­zei­gen, muss eigent­lich der URI http://jendryschik.de/wsdev/trans/designguide/index.xhtml?show=wartbarkeit auf­ge­ru­fen wer­den. Das glei­che gilt ent­spre­chend für alle ande­ren Abschnitte. URIs mit Para­me­ter sind aller­dings nicht son­der­lich schön und auch von Such­ma­schi­nen nicht gern gese­hen. Bes­ser sind URIs nach fol­gen­dem Mus­ter: http://jendryschik.de/wsdev/trans/designguide/wartbarkeit. Mit einer RewriteRule las­sen sich die URIs ent­spre­chend umschreiben:

RewriteRule ^/wsdev/trans/designguide/wartbarkeit$
  wsdev/trans/designguide/index.xhtml?show=wartbarkeit

Aller­dings gibt es 25 Abschnitte, dazu noch die Mög­lich­keit, den gan­zen Essay anzei­gen zu las­sen. 26 Such­mus­ter zu schrei­ben, wäre zeit­auf­wän­dig und würde die htaccess-Datei deut­lich auf­blä­hen. Aber es gibt ja regu­läre Ausdrücke:

RewriteRule ^wsdev/trans/designguide/([^\.]+)$
  /wsdev/trans/designguide/index.xhtml?show=$1

Alle Auf­rufe von URIs, die dem Mus­ter ent­spre­chen, wer­den nun an die tat­säch­lich exis­tie­ren­den URIs wei­ter­ge­lei­tet, wobei der Wert des Para­me­ters aus­ge­le­sen und ent­spre­chend anstelle der Varia­ble $1 ein­ge­fügt wird.

Ein wei­te­res Bei­spiel soll die Mög­lich­kei­ten von mod_rewrite ver­an­schau­li­chen: Die meis­ten Web­sites sind mit und ohne Angabe von »www« erreich­bar. Die­selbe Res­source lässt sich dann sowohl mit dem URI http://www.example.com/foo als auch mit http://example.com/foo adres­sie­ren. Ich ver­wende mod_rewrite dazu, alle Anfra­gen an http://www.jendryschik.de/foo an die ent­spre­chende Adresse ohne das über­flüs­sige »www« weiterzuleiten:

RewriteCond %{HTTP_HOST} ^www.jendryschik\.de$ [NC]
RewriteRule ^(.*) http://jendryschik.de/$1 [R=301]
RewriteCond %{THE_REQUEST} (.*)\.xhtml [NC]
RewriteRule (.*)\.xhtml http://jendryschik.de/$1 [NC,R=301]

Regu­läre Aus­drü­cke machen sehr umfang­rei­che und mäch­tige Such­mus­ter mög­lich. Eine aus­führ­li­che Erläu­te­rung deren Auf­baus ist aller­dings nicht Thema die­ses Arti­kels. Mehr Infor­ma­tio­nen dazu fin­den Sie in den Apache-Manuals oder einem Tuto­rial Ihrer Wahl.

Wei­ter­lei­tung mit PHP

Eine weni­ger kom­plexe und trotz­dem sehr mäch­tige Mög­lich­keit der Wei­ter­lei­tung bie­tet PHP. Mit Hilfe der Funk­tion header() las­sen sich Zei­len in den HTTP-Hea­der ein­fü­gen, sodass der HTTP-Response direkt beein­flusst wer­den kann.

<?php
header("Location: http://www.example.com/");
exit();
?>

Die Funk­tion exit() bewirkt, dass das Par­sen des aktu­el­len Doku­ments abge­bro­chen wird. Dies spart nicht nur Res­sour­cen des Ser­vers; auch sorgt der Abbruch dafür, dass kein HTTP-Body erzeugt wird. Für spe­zi­elle Cli­ents, die der Wei­ter­lei­tung nicht fol­gen kön­nen oder wol­len, kann aber ein sol­cher Body erzeugt werden:

<?php
header("Location: http://www.example.com/");
echo "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n";
echo " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
echo "<html xmlns=\"http://www.w3.org/1999/xhtml\"
  lang=\"de\" xml:lang=\"de\">\n";
echo "  <head>\n";
echo "    <meta http-equiv=\"content-type\"\n";
echo "      content=\"text/html; charset=utf-8\" />\n";
echo "    <title>Weiterleitung</title>\n";
echo "  </head>\n";
echo "  <body>\n";
echo "    <p>Die gesuchte Ressource wurde nach";
echo "      <a href=\"http://www.example.com/\">www.example.com</a>";
echo "      verschoben.</p>\n";
echo "  </body>\n";
echo "</html>";
exit();
?>

Wenn benut­zer­de­fi­nierte Hea­der gesen­det wer­den sol­len, müs­sen Sie aller­dings sicher­stel­len, dass keine Aus­gabe vor dem Sen­den der Hea­der erfolgt. Die sicherste Methode ist, das PHP-Skript so zu schrei­ben, dass die header()-Funk­tion vor jeg­li­cher Aus­gabe erfolgt. Beden­ken Sie, dass Whi­te­space außer­halb der Mar­kie­run­gen <?php und ?> eben­falls eine Aus­gabe darstellt!

Stan­dard­mä­ßig wird auch hier der Sta­tus­code 302 ver­sen­det. Wol­len Sie eine per­ma­nente Wei­ter­lei­tung rea­li­sie­ren, so fügen Sie in obi­ges Skript noch die fol­gende Zeile ein:

header("Status: 301");

Zusätz­lich müs­sen Sie beach­ten, dass HTTP einen abso­lu­ten URI erwar­tet, auch wenn rela­tive URIs in den meis­ten Fäl­len eben­falls zum gewünsch­ten Ergeb­nis füh­ren. Der fol­gende Hea­der ist somit unzulässig:

header("Location: bar");

Falls Sie inner­halb des PHP-Skripts nicht wis­sen, auf wel­cher Domain das Skript ablau­fen wird, oder wenn Sie es auf meh­re­ren Domains ein­set­zen möch­ten, kön­nen Sie die Server-Variable $_SERVER["HTTP_HOST"] nut­zen, um einen zuläs­si­gen Hea­der zu erzeugen:

header("Location: http://" . $_SERVER["HTTP_HOST"] . "/");

Zum Sei­ten­an­fang

Cli­ent­sei­tige Weiterleitung

Eine ser­ver­sei­tige Wei­ter­lei­tung ist nicht für alle Web­au­to­ren rea­li­sier­bar. Bei vie­len bil­li­gen oder kos­ten­lo­sen Web-Hostern besteht keine Mög­lich­keit des Ein­sat­zes von Zugriffs­kon­troll­da­teien oder ser­ver­sei­ti­gen Tech­ni­ken wie PHP. In die­sem Fall steht nur die Mög­lich­keit der cli­ent­sei­ti­gen Wei­ter­lei­tung zur Ver­fü­gung. Das bleibt zwar nur ein schwa­cher Ersatz für eine »rich­tige« Wei­ter­lei­tung, stellt jedoch – spar­sam und mit Bedacht ein­ge­setzt – eine akzep­ta­ble Not­lö­sung dar, wenn­gleich natür­lich kein ent­spre­chen­der Sta­tus­code an den Cli­ent gesen­det wird.

Wei­ter­lei­tung per meta-Ele­ment

Rich­tig ein­ge­setzt, kön­nen Sie das HTML/XHTML-Ele­ment meta dazu ver­wen­den, eine Wei­ter­lei­tung zu simu­lie­ren. In der Pra­xis funk­tio­niert dies recht zuver­läs­sig, wenn­gleich Sie damit natür­lich keine »echte« Wei­ter­lei­tung erset­zen kön­nen. Fol­gende Angabe lei­tet nach 5 Sekun­den nach http://www.example.com/ weiter:

<meta http-equiv="refresh" content="5; url=http://www.example.com/">

Mit dem ers­ten Teil des Wer­tes des Attri­buts content bestim­men Sie, wie lange die aktu­elle Seite, nach­dem sie gela­den ist, ange­zeigt wird, bevor die Wei­ter­lei­tung zum im zwei­ten Teil des Wer­tes ange­ge­be­nen URI erfolgt. Sie kön­nen sowohl abso­lute als auch rela­tive URIs notieren.

Sie soll­ten sich nicht dar­auf ver­las­sen, dass eine sol­che Wei­ter­lei­tung bei jedem Cli­ent zuver­läs­sig funk­tio­niert. Einige Brow­ser kön­nen mit einer Wei­ter­lei­tung per meta-Ele­ment nichts anfan­gen, in ande­ren kann man diese Funk­tio­na­li­tät abstel­len, sogar im Inter­net Explo­rer. Zur Sicher­heit notie­ren Sie einen nor­ma­len Link zur Wei­ter­lei­tungs­adresse. Das hat zudem den Vor­teil, dass Such­ma­schi­nen der Wei­ter­lei­tung fol­gen und die Ziel­res­source in den Index auf­neh­men können.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="de" xml:lang="de">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta http-equiv="refresh" content="0; url=http://www.example.com/" />
    <title>Weiterleitung</title>
  </head>
  <body>
    <p>Die gesuchte Ressource wurde nach <a href="http://www.example.com/">www.example.com</a> verschoben.</p>
  </body>
</html>

Wei­ter­lei­tung mit JavaScript

Der Voll­stän­dig­keit hal­ber sei erwähnt, dass sich mit cli­ent­sei­ti­gen Skript­spra­chen wie Java­Script eben­falls Wei­ter­lei­tun­gen rea­li­sie­ren las­sen, bei­spiels­weise wie folgt:

<script type="text/javascript">
  window.location.href='http://www.example.com/';
</script>

Davon möchte ich jedoch abra­ten. Wei­ter­lei­tung mit Java­Script und per meta-Ele­ment tei­len sich die glei­chen Nach­teile, wobei die Wahr­schein­lich­keit, dass der Nut­zer die JavaScript-Unterstützung sei­nes Cli­ents abge­schal­tet hat, ungleich grö­ßer ist. Ich kann mir nur einen prak­ti­schen Anwen­dungs­fall vor­stel­len, bei dem eine JavaScript-Lösung dem oben vor­ge­stell­ten meta-Ele­ment vor­zu­zie­hen ist: Wei­ter­lei­tung auf einen Teil der Web­site, der Java­Script erfor­dert, mit Dar­stel­lung von Alter­na­ti­vin­hal­ten im aktu­el­len Weiterleitungsdokument.

1 Kommentar

  1. Pingback: 301 “Redirect” – Suchmaschinenfreundliche Weiterleitung | Private Homepage von Joachim Nadolny

Hinterlasse eine Antwort

Pflichtfelder sind mit * markiert.

*