Post-Redirect-Get-Pattern

Das Google Crawl-Budget und Linkjuice optimieren mit PRG

Die interne Linkstruktur effektiv aufräumen: Vor allem in Onlineshops ist es ein bekanntes Problem – durch die Filternavigation entstehen Unmengen von Unterseiten, die für die interne Linkstruktur Gift sind. Eine optimale interne Verlinkung ist aber ein entscheidender Ranking-Faktor, siehe dazu auch den Wiki-Beitrag Siloing: Bessere Relevanz bei Google und User. Um sicherzustellen, dass der Google Bot irrelevante Links beim Crawlen ignoriert, kommt im SEO die Technik der Linkmaskierung zum Einsatz. Grundsätzlich stehen hier verschiedene Methoden zur Auswahl. Die Unterseiten können in der robots.txt gesperrt, mit den Attributen nofollow oder noindex ausgezeichnet oder mit dem Tag Canonical versehen werden. Auch eine Maskierung mit JavaScript ist möglich, wobei Google diese Links mittlerweile ausliest. Der Bot crawlt auch weiterhin noindex- und Canonical-Links, der Crawling-Aufwand reduziert sich also nicht. Das Setzen von nofollow verhindert die Weitergabe der Linkpower innerhalb der Website. Diese Nachteile hat die Maskierung via PRG-Pattern nicht.

Die Funktionalität des Post-Redirect-Get-Patterns

Mit dem PRG-Pattern werden Filter-Links als Post-Formular umgesetzt. Wenn der User auf einen Filter-Link klickt, wird eine Post-Anfrage an den Server geschickt. Dieser antwortet aber nicht mit dem Anzeigen der gewünschten Seite, sondern mit einem Redirect auf die Quellseite. Erst jetzt werden dort die angefragten Informationen angezeigt. Die Linkstruktur bleibt sauber, da der Google-Bot dem Post-Formular nicht folgt und keine neue URL erzeugt wird.

Schritt für Schritt sieht die Umsetzung folgendermaßen aus:

  1. Auf jeder Seite existieren ein verstecktes (display: none bzw. visibility: 0) Formular-Element und ein unsichtbares (hidden) Input-Element.
  2. Die Übertragungsmethode des Formulars muss auf “post” eingestellt sein. Das Formular wird auf eine vordefinierte URL verschickt, unter welcher ein serverseitiges Script zum Bearbeiten der Requests läuft (siehe Punkt 6).
  3. Das Input-Feld hat keinen Wert (value="").
  4. Maskierte Links werden im HTML als span-Elemente dargestellt und per CSS als Link nachempfunden. In einem Attribut (z. B. data-submit) enthält jedes span-Element die base64-codierte Ziel-URL.
  5. Ein Klick auf einen maskierten Link wird per Javascript onclick-Events abgefangen. Die base64-codierte Ziel-URL wird aus dem jeweiligen Attribut ausgelesen und als Wert in das input-Feld eingefügt. Das Formular wird dann per Javascript submit-Event abgeschickt.
  6. Das serverseitige Script empfängt die PRG-Requests, decodiert die base64-codierte Ziel-URL und erzeugt einen 302-Redirect auf die decodierte Ziel-URL.
  7. Falls der übergebene Parameter leer ist, wird ein 302-Redirect auf die Startseite erzeugt.

 

Konkrete Code-Beispiele

Zur Verdeutlichung des Funktionsprinzips dienen folgende Code-Beispiele. Als serverseitige Programmiersprache wurde PHP verwendet, eine Umschreibung auf Java sollte jedoch mit geringem Aufwand möglich sein. 

  • Formular:
    1. <form id="redirform" action="/redir.php" method="post">
     2.  <input type="hidden" name="redirdata" id="redirdata">
     3. </form>
  • Link-Element:
    1. <span class="btn redir-link" data-submit="<?=base64_encode('http://www.domain.com/testurl/') ?>">
    looks like a link and redirects via PRG</span>


  • Serverseitiges Script PHP (prg.php):
    1. function prgRedirect()
    2. {
    3.   $location = "https://www.domain.com/";
    4.   if(!empty($_POST['redirdata']))
    5.   {
    6.      $url = base64_decode($_POST['redirdata']);
    7.      if(strstr($url, $location) !== false)
    8.      {
    9.        $location = $url;
    10.      } 
    11.      else if(strstr($_SERVER['HTTP_REFERER'], $location) !== false)
    12.      { 
    13.        $location = $_SERVER['HTTP_REFERER'];
    14.      }
    15.    }
    16.    header("Location: " . $location, true, 302);
    17.    exit();
    18. }
    19. prgRedirect();

  • JavaScript (jQuery voraus):
    1. $(function() {
    2.   $('.redir-link[data-submit]').click(function (e) {
    3.     e.preventDefault(); 
    4.     var $this = $(this),
    5.       $redirectForm = $('#redirform'),
    6.       $redirectValue = $('#redirdata'),
    7.       value = $this.data('submit');
    8.
    9.     $redirectValue.val(value);
    10.    $redirectForm.submit();
    11.   });
    12. });

  • CSS
    1. #redirform {display:none;}
    2. .btn {color: blue; cursor: pointer;}
    3. .btn:hover {text-decoration: underline;} 

     

    HTML auslagern und per AJAX nachladen

    Zum Einsatz von PRG-Pattern empfiehlt es sich, das gesamte HTML der Navigation auszulagern und nicht direkt im Quellcode der Seite zu platzieren. Das HTML lässt sich über AJAX nachladen. Dazu wird ein DIV-Element ohne Inhalt im Quellcode platziert, welches mit dem nachgeladenen HTML befüllt wird. Zudem sollte das Skript, welches das HTML zurückliefert (in unserem Beispiel: “/navi.php?menu=filter”), den HTTP-Header “X-Robots-Tag: noindex, nofollow” setzen.

    Beispiel HTML: 

    <div id="navi"></div>

    Beispiel jQuery: 

    $.get('/navi.php?menu=filter', function(data)
    {
      $("#navi").html(data);
    });

    Referenzen und weiterführende Links zu "PRG-Pattern: Die interne Linkstruktur effektiv aufräumen“


    Fragen oder Kommentare? Das One Team antwortet gerne.

    5 Kommentare
    • Ben Küstner
      Ben Küstner
      schrieb am 30.06.2016, 01:04 Uhr

      Sehr geil. Endlich haut\'s mal einer raus, dass die non Techies es auch mal checken.

      » Antworten
    • Christian
      Christian
      schrieb am 20.07.2016, 12:36 Uhr

      Ich nutze diese Art von Maskierung auch auf einigen Seiten - nur ohne JS und es funktioniert trotzdem zwinker Habe es auch mit diversen Tests überprüft. Eine Gute Anleitung - auch wenn sich jetzt einige SEOs ärgern, dass sie dieses Wissen nun nicht mehr exklusiv haben - ich kann sie beruhigen - ein nicht Techi kann es nicht so einfach umsetzen.

      VG
      Christian

      » Antworten
    • Fabian
      Fabian schrieb am 12.08.2016, 10:47 Uhr

      erstmal danke für die Anleitung, aber könnt ihr bitte erklären wozu die Zeilen 7 - 15 dienen wenn die variable $location in Zeile 16 nicht verwendet wird.

      Danke smile

      » Antworten
    • Andrey
      Andrey schrieb am 16.08.2016, 14:36 Uhr

      Hallo Fabian,

      berechtigter Einwand, in Zeile 16 muss natürlich $location statt $url stehen, dies haben wir nun korrigiert. Vielen Dank für den Hinweis :-)

      Beste Grüße
      Andrey

      » Antworten
    • Patrick
      Patrick schrieb am 07.10.2016, 14:06 Uhr

      Danke für den guten Artikel, ist eine Gute Mischung aus grundsätzlicher Funktionserklärung und How-to-do.

      » Antworten