24 July 2011 Browser, History, HTML5, Javascript Robert Muehsig

Der Begriff “Hash-Bang” klingt irgendwie etwas blöd, aber es ist im Grunde nur die “Lautschrift” von einer Raute und einem Ausrufezeichen - im englischen: “#!”. Der Begriff kam auf, als einige Internetseiten anfingen anstatt “normale” URLs zu verwenden eine Adresse mit “#!” vorkam (z.B. http://lifehacker.com/#!5753509/hello-world-this-is-the-new-lifehacker). Wichtig ist das “#!”. Eine “ganz normale” URL sieht z.B. so aus: http://www.google.com/search?q=hello+world.

Eine URL besteht aus mehreren Teilen, z.B. die Domain und der Pfad und am Ende noch ein Parameter. Der oder die Parameter werden durch ein führendes Fragezeichen “?=” vom Rest der URL getrennt. Ganz normal halt.

Das Problem kam mit AJAX

Es gibt ein paar Probleme bei AJAX Anwendungen. Durch Javascript und die geladenen Daten kann man sehr einfach die DOM verändern. Dadurch lassen sich sehr dynamische Seiten erstellen, jedoch ändert sich die URL dabei nicht! Für den Browser befindet man sich immer noch auf der selben Seite, egal wie viele AJAX Requests man gemacht hat.

Nun begegnen wir ein paar Problemen:

- Die Browser Navigation ist “ausgeschaltet”. Prominentes Beispiel hier ist der Back-Button des Browsers. Da sich die Browser-History nicht geändert hat, springt der Browser einfach auf die letzte Seite die er kennt. Dabei kann der Nutzer allerdings auf eine komplett andere Seite geleitet werden, obwohl er “nur” ein Schritt zurück gehen wollte.

- Ohne bestimmte URL kann man auch keine Links verschicken. Je nach Anwendung kann das mehr oder weniger schlimm sein.

- SEO ist auch noch ein Thema für sich. Javascript/AJAX und Suchmaschinen mögen sich nicht sonderlich und wenn man alles unter einer Adresse laufen hat, wird es wahrscheinlich nix mit dem Besucherstrom von Google. Auch hierbei ist natürlich die Frage ob SEO wichtig ist oder nicht.

Ein Beispiel wo jedenfalls die ersten beiden Probleme auftreten ist Google Maps. Man startet bei “http://maps.google.com” und egal ob ich ran oder wegzoome, die URL ändert sich nicht.

image

 

Keine Änderungen in der URL beim Zoomen:

image

Nun geht natürlich auch der Browser-Back Button nicht und man kann nicht einfach den Link aus der Adresszeile kopieren. Google ist natürlich nicht doof: Natürlich haben sie einen Mechanismus eingebaut um den Ausschnitt als Link zu verschicken, jedoch über Umwege.

Wo liegt das Problem?

Über AJAX bzw. Javascript können wir die DOM ohne Probleme weitestgehend verändern, jedoch nicht elegant die URL ändern. Es gibt natürlich einen unschönen Weg:

<script type="text/javascript">
     location.href='http://www.code-inside.de';
</script> 

 

Hierbei wird allerdings ein kompletter Page-Reload ausgelöst – das würde in AJAX Anwendungen keinen Sinn machen. Es gibt allerdings eine Ausnahme. Der Anker (oder das URL Fragment nach der “#”) kann verändert werden ohne das ein Page-Reload ausgelöst wird:

Die Ausnahme: Der Anker ( # )

Bekannt ist der Anker bei einem A-Tag. Man kann den Browser veranlassen zu einer bestimmten Stelle zu gehen. Dieser Teil ist nach dem # (Hash) aufgeführt.

image

Der Anker kann auch via Javascript aufgerufen werden:

window.location.hash="HelloWorld"; 

 

Dabei wird kein Page-Reload ausgeführt! Die Browser-Navigation funktioniert auch (Browser-Back Button) und man kann auch die Links verschicken.

Dann wird es jedoch etwas knifflig…

Wenn wir die Probleme von oben beseitigen wollen, müssen wir über diesen Umweg die History bearbeiten. Wenn man diesen Weg einschlägt um die Browser History wieder zu kitten bekommt man natürlich gleich neue Probleme: Was passiert wenn jemand den Link verschickt? Nehmen wir das Beispiel Google Maps: Wenn ich dem Nutzer anbiete den Link zu verschicken muss ich natürlich darauf auch wieder reagieren. Das kann doch zu einem recht großes K(r)ampfgebiet werden.

Diese Problemstellungen tauchen am meisten bei Single-Page-Apps auf. D.h. am Anfang gibt es einen großen Page-Load und der Rest wird via AJAX gemacht.

Nun zu den Hash-Bangs

Zu der ursprünglichen Frage: Hash-Bang URLs sind aus der Not geboren um die URL via Javascript auch zu verändern. Damit hat man auch in AJAX Anwendungen volle Kontrolle und man beseitig die beschriebenen Probleme. Ein bekannter Vertreter ist z.B. Twitter:

image

Es gab vor einiger Zeit eine Diskussion ob diese Art der URLs gut oder schlecht sind, allerdings ist die Rettung in Sicht:

Die PushState API!

Durch diese API kann man die URL via Javascript ändern – funktioniert leider nur in modernen Browsern. Aber auch hier gibt es schon ein bekannten Vertreter: GitHub (wenn man sich durch einen Source Tree navigiert).

Javascript Frameworks

Für beide Arten (die Hash-Variante) und die PushState API gibt es bereits Frameworks, sodass man damit leichter arbeiten kann. Zum Teil wird auch geprüft ob der Browser die PushState API hat oder nicht und als FallBack wird die “alte” Variante genommen:

- Backbone.js

- History.js

- jQuery BBQ

- …

Auf meinem ToDo Zettel steht auch eine Demo-Anwendung mit Backbone.js – daher passt dieser Blogpost auch ganz gut in diese Reihe Zwinkerndes Smiley


Written by Robert Muehsig

Software Developer - from Dresden, Germany, now living & working in Switzerland. Microsoft MVP & Web Geek.
Other Projects: KnowYourStack.com | ExpensiveMeeting | EinKofferVollerReisen.de

If you like the content and want to support me you could buy me a beer or a coffee via Litecoin or Bitcoin - thanks for reading!