Teil von SELFHTML aktuell Teil von Artikel Teil von JavaScript

Bookmarklets

nach unten RobertBienert
nach unten Hinweise zum Thema
nach unten Beispiel mit Erläuterungen: Anzeige der User-Agent-Kennung
nach unten Beispiel mit Erläuterungen: Browser-Kompatibilitätsmodus
nach unten Beispiel mit Erläuterungen: Manipulation der Fenstergröße
nach unten Beispiel mit Erläuterungen: Seite validieren
nach unten Beispiel mit Erläuterungen: Cookie-Editor
nach unten Umfangreichere Bookmarklets und Sicherheitshinweise
nach unten Abschließend
nach unten Weiterführende Links

Robert Bienert

E-Mail: E-Mail robertbienert@gmx.net
Homepage-URL: deutschsprachige Seite http://www.robertbienert.de/

Bei Fragen zu diesem Beitrag bitte den Autor des Beitrags kontaktieren!

nach obennach unten

Hinweise zum Thema

Dieser Artikel beschreibt anhand einiger Beispiele sogenannte Bookmarklets. Das sind kurze JavaScript-Schnipsel, die als Lesezeichen im Browser abgespeichert werden. Bookmarklets können sowohl dazu dienen, Informationen über die aktuelle Webseite und über den Browser selbst zu erhalten als auch dazu, Einstellungen wie etwa in Bezug auf die Fenstergröße auszulesen und zu ändern. Bookmarklets werden als ganz normale Bookmarks (andere übliche Bezeichnungen: Lesezeichen oder Favoriten) abgelegt, daher auch der erste Teil des Namens. Dies geschieht allerdings beginnend mit dem Pseudo-Protokoll javascript:.

Um ein Bookmarklet aus diesem Artikel zu speichern, wählen Sie am besten den Menüpunkt Link als Bookmark hinzufügen oder ähnlich, die genaue Bezeichnung hängt von Ihrem Browser ab. Sie können aber auch den kompletten Code in die Adresszeile eingeben und dann diese URL sichern.

Damit die hier vorgestellte Technik sowie die folgenden Beispiele funktionieren, müssen Sie JavaScript in Ihrem Browser aktiviert haben.

Die meisten hier vorgestellen Anwendungsmöglichkeiten von Bookmarklets öffnen neue Browserfenster oder stellen ihre Information in einem bereichsübergreifende Seite JavaScript-Dialogfenster dar. Das bedeutet, dass Sicherheitseinstellungen oder Popup-Blocker die Funktionalität beeinträchtigen können.

Mit Layoutvorgaben für ein neues Browserfenster sollte man dabei vorsichtig umgehen:

nach obennach unten

Beispiel mit Erläuterungen: Anzeige der User-Agent-Kennung

Popup-Seite Anzeigebeispiel: So sieht's aus

<a href="javascript:alert(navigator.userAgent)">Anzeigebeispiel</a>

Erläuterung:

Beim Anklicken des obigen Links wird in einem bereichsübergreifende Seite JavaScript-Dialogfenster die bereichsübergreifende Seite User-Agent-Kennung Ihres Browsers angezeigt.

Beachten Sie:

In einigen Webbrowsern, unter anderem dem Internet Explorer, kann man den Text des Dialogfensters nicht markieren und in die Zwischenablage kopieren, das heißt, der User-Agent wird nur angezeigt. Man kann die gewünschte Information aber auch über document.write in ein eigenes Dokument schreiben, aus dem sie sich herauskopieren lassen:

Portable, komfortable Variante:

Popup-Seite Anzeigebeispiel: So sieht's aus

<a href="javascript:window.open('about:blank', '_blank', 'width=480,height=100,menubar=no,toolbar=no,status=no,location=no').document.write(navigator.userAgent)">
Anzeigebeispiel</a>

Erläuterung:

Beim Anklicken des obigen Links wird in einem bereichsübergreifende Seite neuen Browserfenster ('_blank' als zweiter Parameter) die bereichsübergreifende Seite User-Agent-Kennung Ihres Browsers angezeigt; mit Copy&Paste können Sie diesen Wert nun anderweitig weiterverwenden, da es sich bei dem Popup-Fenster um ein ganz normales Browser-Fenster handelt. Die Größen-Angaben width=480 und height=100 sind willkürlich gewählt und können den Gegebenheiten des verwendeten Bildschirms angepasst werden. Damit dieses (sogenannte Popup-Fenster) mit der eigenen Größe möglichst effizient umgeht, werden sämtliche Werkzeug-Leisten ausgeblendet (menubar=no,toolbar=no,status=no,locationbar=no). Dabei werden die oben bereits erwähnten Nachteile solcher Beschränkungen hier zur Demonstration in Kauf genommen. Der Rückgabewert der Methode bereichsübergreifende Seite window.open ist das neu geöffnete Fenster, in dessen Unterobjekt bereichsübergreifende Seite document die User-Agent-Kennung geschrieben wird.

Beachten Sie:

Opera 9 (Betaversion) bereitet dieses Beispiel (noch) Probleme.

nach obennach unten

Beispiel mit Erläuterungen: Browser-Kompatibilitätsmodus

Popup-Seite Anzeigebeispiel: So sieht's aus

<a href="javascript:alert(document.compatMode)">Anzeigebeispiel</a>

Erläuterung:

Moderne Webbrowser (Internet Explorer 6.0, Mozilla Firefox, Opera) bieten die Dokumenteigenschaft compatMode an, mit der man abfragen kann, in welchem Komatibilitätsmodus der Browser die aktuelle Seite anzeigt; aktuelle Seite heißt in diesem Zusammenhang, dass beim Aufrufen dieses Bookmarklets der Kompatibilitätsmodus des Dokumentes im aktuellen Fenster (und Tab) angezeigt wird. Obiger Link zeigt z.B. für diesen Artikel "BackCompat", d. h. diese HTML-Datei wird abwärtskompatibel dargestellt. Es gibt aber auch mindestens noch den Wert "CSS1Compat", also CSS1-kompatibel.

Beachten Sie:

Dieses Bookmarklet funktioniert nicht mit älteren Browsern sowie nicht im Safari. Dort ist die Eigenschaft document.CompatMode unbekannt und es wird dem entsprechend undefined zurückgegeben.

nach obennach unten

Beispiel mit Erläuterungen: Manipulation der Fenstergröße

Popup-Seite Anzeigebeispiel: So sieht's aus

<a href="javascript:while(isNaN(weite=parseInt(window.prompt('Geben Sie für die gewuenschte Breite des Fensters in Pixeln\neinen numerischen Wert von mindestens 100 ein:','')))||weite<100);while(isNaN(hoehe=parseInt(window.prompt('Geben Sie für die gewuenschte Hoehe des Fensters in Pixeln\neinen numerischen Wert von mindestens 100 ein:','')))||hoehe<100);void window.open(location.href,'_blank','location=yes,menubar=yes,resizable=yes,scrollbars=yes,status=yes,toolbar=yes,width='+weite+',height='+hoehe)">Anzeigebeispiel</a>

Erläuterung:

Dieses Bookmarklet öffnet die aktuelle Seite in einem Fenster in der vom Anwender vorgegebenen Größe. Dazu werden die gewünschte Fensterbreite sowie -höhe mit bereichsübergreifende Seite window.prompt abgefragt und und anschließend ein neues Browser-Fenster der gewählten Größe mit der Methode bereichsübergreifende Seite window.open geöffnet. Die URL der aktuellen Seite wird dabei der Eigenschaft bereichsübergreifende Seite location.href entnommen. Ein solches Bookmarklet ist praktisch, wenn man, ohne die Einstellung selbst zu ändern, in etwa abschätzen will, wie ein Dokument bei verschiedenen Fenstergrößen und Bildschirmauflösungen aussieht. (auch wenn man bereichsübergreifende Seite nicht für bestimmte Bildschirmauflösungen schreiben sollte). Im Code ist vorgegeben, dass ein Fenster mindestens 100*100 Pixel groß sein muss, Sie können natürlich dort auch höhere Werte angeben (kleinere Fenstergrößen sind aus Sicherheitsgründen nicht zulässig).

Mit knapp 500 Zeichen ist dieses Codestück ein schönes Beispiel für englischsprachige Seite obfuscated code. Deshalb sei es im Folgenden noch einmal übersichtlich mit Einrückungen und in mehreren Zeilen dargestellt:

while (isNaN(weite = parseInt(window.prompt('Geben Sie für die gewuenschte Breite des Fensters in Pixeln' +
        '\neinen numerischen Wert von mindestens 100 ein:', '')))
    || weite < 100)
    ;
while (isNaN(hoehe = parseInt(window.prompt('Geben Sie für die gewuenschte Hoehe des Fensters in Pixeln' +
        '\neinen numerischen Wert von mindestens 100 ein:', '')))
    || hoehe < 100)
    ;
void window.open(this.location.href,'_blank',
    'location=yes,menubar=yes,resizable=yes,scrollbars=yes,
    status=yes,toolbar=yes,width='+weite+',height='+hoehe)

In den beiden while-Schleifen wird solange nach einer Größe gefragt, bis JavaScript einen ganzzahligen Wert über 100 erhält. Die Semikolons, die direkt auf die while-Bedingungen folgen, bewirken, dass im "Körper" der Schleife keine Anweisungen ausgeführt werden.

Beachten Sie:

Dieses Beispiel sprengt von der Codelänge (etwa 500 Zeichen) her fast den Rahmen des in einigen Browsern möglichen (508 Zeichen; siehe nach obenoben). Denken Sie daran, falls Sie es ändern möchten. Ein bisschen Platz können Sie dabei durch Umbennen der Variablen weite und hoehe, etwa in w und h, gewinnen.

Der bereichsübergreifende Seite void-Operator ersetzt den Rückgabewert von window.open durch den Wert undefined. Ansonsten würde der komplette Inhalt der aufrufenden Seite durch die Zeichenkette "[Object]" bzw. "[object Window]" überschrieben.

nach obennach unten

Beispiel mit Erläuterungen: Seite validieren

Popup-Seite Anzeigebeispiel: So sieht's aus

<a href="javascript:if(location.protocol=='http:'||location.protocol=='https:')location.href='http://validator.w3.org/check?uri='+encodeURIComponent(location.href)">Anzeigebeispiel</a>

Mit Hilfe dieses Bookmarklets können Sie die aktuell angezeigte Seite auf gültiges HTML validieren. Dazu wird der in der Eigenschaft bereichsübergreifende Seite location.href gespeicherten URL der Seite die Adresse des englischsprachige Seite W3C-Validators vorangestellt und die neue Seite durch Setzen von location.href auf diesen Wert aufgerufen. Da der W3C-Validator lediglich HTML-Dokumente über die Protokolle HTTP und HTTPS abrufen kann, wird zuerst durch Abfragen von bereichsübergreifende Seite location.protocol sichergestellt, dass dies der Fall ist. Damit weiterhin Sonderzeichen oder Bestandteile des Querystrings korrekt übergeben werden, maskiert das Skript mit Hilfe der Funktion bereichsübergreifende Seite encodeURIComponent die Original-URL. Um die Funktionsweise des Bookmarklets besser erkennen zu können, ist der JavaScript-Code noch einmal formatiert dargestellt:

if (location.protocol == 'http:' || location.protocol == 'https:')
    location.href = 'http://validator.w3.org/check?uri=' +
        encodeURIComponent(location.href)

Durch Ändern der Validator-Adresse können Sie aus diesem Beispiel Bookmarklets zur Prüfung des CSS-Codes oder einen Link-Checker machen, dazu müssen Sie lediglich den URL-Bestandteil http://validator.w3.org/check?uri= durch folgendes Ersetzen:

nach obennach unten

Beispiel mit Erläuterungen: Cookie-Editor

Popup-Seite Anzeigebeispiel: So sieht's aus

Rufen Sie dieses Anzeigebeispiel bitte dreimal auf; einmal bevor, ein weiteres Mal, nachdem Sie ein Cookie gesetzt, und ein drittes Mal, nachdem Sie es verändert haben.

Jetzt Cookie setzen

<a href="javascript:if(document.cookie){k=document.cookie.split('; ');w=window.open('about:blank','_self');for(i=0;i<k.length;++i)w.document.write('<input type=&quot;text&quot; value=&quot;'+k[i]+'&quot; size=&quot;50&quot;>');w.document.write('<button type=&quot;button&quot; onclick=&quot;var ins=document.getElementsByTagName(\'input\');for(i=0;i<ins.length;++i)document.cookie=ins[i].value;location.href=\''+location.href+'\'&quot;>Speichern und zurück</button>');}else alert('Sie haben keine Cookies von dieser Seite.');">Cookie-Editor</a>

Mit Hilfe dieses sehr langen (über 500 Zeichen) und komplexen Bookmarklets lassen sich die von einer Seite im Browsercache abgelegten Cookies betrachten und manipulieren. Der besseren Übersicht halber sei es hier zunächst nochmals in mehreren Zeilen dargestellt:

if (document.cookie) {
    k = document.cookie.split('; ');
    w = window.open('about:blank', '_self');

    for (i = 0;i < k.length; ++i)
        w.document.write('<input type="text" value="' +
        k[i] + '" size="50">');

    w.document.write('<button type="button" onclick="' +
        'var ins=document.getElementsByTagName(\'input\');' +
        'for(i=0;i<ins.length;++i)document.cookie=ins[i].value;' +
        'location.href=\''+location.href+'\'">Speichern und zur&uuml;ck</button>');
}
else
    alert('Sie haben keine Cookies von dieser Seite.');

Erläuterung:

Durch Abfrage der Eigenschaft bereichsübergreifende Seite document.cookie ermittelt das Bookmarklet, ob der Browser Cookies von der aktuellen Seite gespeichert hat. Falls dies der Fall ist, wird der Cookie-String mit der Methode bereichsübergreifende Seite String.split in ein Array zerlegt, wobei man davon ausgehen kann, dass die in document.cookie gespeicherten Cookies jeweils durch „“, also ein Semikolon, gefolgt von einem Leerzeichen voneinander getrennt sind. Zur Ausgabe der Cookies wird ein neues Dokument geöffnet. Mit der Methode bereichsübergreifende Seite document.write() werden in dieses 50 Zeichen breite bereichsübergreifende Seite Eingabefelder geschrieben, die jeweils ein Cookie enthalten. Abschließend erhält diese Ausgabe noch einen bereichsübergreifende Seite Klickbutton, mit dem die geänderten Cookies gespeichert werden und über den man zur vorherigen Seite gelangt. Der komplette Code für das Speichern der Cookies befindet sich dabei im onclick-Handler des Buttons und ist hier der Übersichtlichkeit halber noch einmal dargestellt:

var ins = document.getElementsByTagName('input');

for (i = 0; i < ins.length; ++i)
    document.cookie = ins[i].value;

Im oben dargestellen Code werden alle input-Felder des Cookie-Editors durchlaufen und ihr in der Eigenschaft bereichsübergreifende Seite value gespeicherter Formular-Wert als Cookie gesetzt. Die letzte Anweisung sorgt dafür, dass nach dem Anklicken des Buttons die vorherige Seite erneut aufgerufen wird:

w.document.write('<button type="button" onclick="' +
                /* oben erläuterter Code */
                'location.href=\''+location.href+'\'">…</button>');

Die vorherige URL wird hier direkt als String in die Ausgabe geschrieben, so dass diese beim Anklicken durch die erneute Zuweisung an bereichsübergreifende Seite location.href noch einmal geladen wird; aus diesem Grund müssen außerdem die einfachen Anführungszeichen maskiert werden.

Beachten Sie:

Da beim Speichern alle <input>-Felder durchlaufen werden, verwendet dieser Cookie-Editor zum Speichern einen <button>.

Dieser Cookie-Editor hat den Nachteil, dass nach dem Neusetzen der Cookies diese nur noch bis zum Ende der Session gültig sind, d.h. solange der Browser geöffnet ist. Der Grund dafür ist, dass nicht vorgesehen ist, dass clientseitige Skripte die weiteren Attribute eines Cookies wie Gültigkeit oder Pfad auslesen können. Das Setzen einer bestimmten Dauer wäre auch insofern falsch, da es so genannte Session-Cookies zu lange bestehen ließe. Dieser Nachteil wird allerdings dadurch ausgeglichen, dass die meisten Seiten Session-Cookies bei jedem Aufruf eines Dokumentes erneuern.

Mit JavaScript ist es zwar nicht möglich, Cookies zu löschen, wie man schnell herausfindet, wenn man ein Eingabefeld des Editors leert oder einem Cookie keinen Wert zuweist, allerdings können mit diesem Bookmarklet neue Cookies erzeugt werden; die Voraussetzung dafür ist allerdings, dass schon mindestens ein Cookie von der Seite im Browsercache gespeichert ist. Ein neues Cookie wird angelegt, indem man eines oder mehrere der Eingabefelder mit einem neuen Schlüssel-Wert-Paar belegt, wodurch beim Speichern vorherige Cookies nicht überschrieben werden.

Der Cookie-Editor funktioniert nicht mit dem Safari 1.3.

nach obennach unten

Umfangreichere Bookmarklets und Sicherheitshinweise

Wie bereits an einigen Stellen genannt, existieren in der Praxis Maximallängen für den Bookmarkletcode. Es gibt Anwendungsfälle, für die das vorgegebene Limit zu gering ist. In solchen Fällen kann man einen Teil des Bookmarklet-Codes in eine externe Datei ausgliedern und diese vom Bookmarklet einbinden lassen. Der folgende Code verdeutlicht dies:

document.write('<script type="text/javascript" src="http://www.example.com/bookmarklet/helper.js"></script>');
bookmarkletFunktion();

Für dieses Beispiel stellt die Datei http://www.example.com/bookmarklet/helper.js eine "öffentliche" Funktion namens bookmarkletFunktion zur Verfügung. Damit benötigt der angegeben Code als Bookmarklet knapp 150 Zeichen, obwohl die Funktion deutlich umfangreicher sein kann. Damit ist der Programmablauf in eine externe Datei ausgelagert und das eigentliche Bookmarklet ist nur noch ein Wrapper um den Code.

Beachten Sie:

Die prinzipielle Möglichkeit eines Bookmarklets, Code aus dem Internet nachzuladen, hat nicht nur Vorteile (Implementierung aufwändiger Anwendungen), sondern birgt auch Risiken: Der eingebundene Code entzieht sich Ihrer Kontrolle, da dieser bei jedem Zugriff wieder neu aus dem Internet geladen wird und dabei zwischen zwei Aufrufen geändert worden sein kann. Ein installiertes Bookmarklet kann damit nachträglich eine Schadfunktion erhalten, ohne dass der Benutzer es merkt. Die Angriffsmöglichkeiten sind dabei mit denen beim so genannten deutschsprachige Seite Cross-Site Scripting vergleichbar. Einige Beispiele zeigen sehr schön, dass das Bookmarklet vollen Zugriff auf das DOM einer Webseite hat und wie einfach die Seite nachträglich verändert werden kann. Ein Unterschied zum Cross-Site-Scripting ist allerdings, dass das Bookmarklet eine Seite verändern kann, ohne in diese injiziert worden zu sein. Damit liegt die Scripting-Schwachstelle eindeutig beim Benutzer und nicht beim Betreiber der Seite.

nach obennach unten

Abschließend

Die oben dargestellten Beispiele sollen an dieser Stelle Anregung genug sein, eigene JavaScript-Schnipsel für seine Lesezeichen anzulegen. Lediglich der Funktionsumfang von JavaScript sowie eine eventuelle Längenbeschränkung von URLs setzen Ihnen dabei gewisse Grenzen. Bookmarklets können durchaus für „Obfuscated-JavaScript”-Wettbewerbe geeignet sein, da der komplette Code in einer Zeile ohne (unnötige) Leerzeichen steht. Bookmarklets erheben nicht den Anspruch der Leserlichkeit. Eine Kommentierung des Bookmarkletcodes ist mit /* Kommentar */ zwar möglich, geht aber ebenfalls zu Lasten des verfügbaren URL-Platzes und erleichtert dabei kaum das Codeverständnis.

Falls Sie allerdings zu der eher unkreativen Sorte Menschen gehören oder einfach das Rad nicht neu erfinden möchten, können Sie nach unten unten oder mit Suchmaschinen unter dem Stichwort Bookmarklets mittlerweile reichhaltige Sammlungen davon im Internet finden.

nach obennach unten

Weiterführende Links

Die folgenden Stellen werden empfohlen, um diesen Artikel besser zu verstehen, oder um weitere Möglichkeiten und Details zu erfahren.

deutschsprachige Seite Toms Stichpunkte rund ums Web: Stichpunkt Bookmarklets
deutschsprachige Seite Wikipedia: Bookmarklet
bereichsübergreifende Seite SELFHTML: JavaScript/Objektreferenz window
bereichsübergreifende Seite SELFHTML: JavaScript/Objektreferenz document
bereichsübergreifende Seite SELFHTML: JavaScript/Objektreferenz location
bereichsübergreifende Seite SELFHTML: JavaScript/Objektreferenz navigator
englischsprachige Seite Gecko DOM Reference: compatMode
englischsprachige Seite MSDN HTML and DHTML Reference: compatMode
englischsprachige Seite The Opera 7 and 8 DOCTYPE Switches
englischsprachige Seite Wikipedia: Obfuscated code (Begriffsklärung)

Teil von SELFHTML aktuell Teil von Artikel Teil von JavaScript

© 2007 bereichsübergreifende Seite Impressum, für diese Seite: E-Mail robertbienert@gmx.net