Homepagebau
Dateiversion:
diesen Beitrag diskutieren,
ergänzen, eine Frage stellen

Bugs in Browsern

Schwierigkeitsgrad:

 

Bug-Report:

 

Irgendjemand hat mir mal gesagt, man müsse sich nur an die Vorgaben der jeweiligen Standards halten und schon funktionieren Webseiten problemlos auf jedem Browser der Welt... schön wär's.

Tatsache ist, dass eigentlich alle Browser sich zwar ungefähr an den Vorgaben des W3C-Standards orientieren, aber wirklich erfüllt werden sie praktisch nie.

 

Dieser Report soll ihnen die schmerzlich gesammelten Erkenntnisse aus mehreren Jahren Umgang mit nicht erfüllten Standards und Programmierfehlern vermitteln und Lösungsvorschläge anbieten.

 

Fehler in Browsern:

 

Y2K-Fehler
betrifft: 6.xx 6.xx

Es gibt einen Y2K-Bug in Netscape und Opera bis zur Version 6. Dabei liefert Date.getYear() leider nicht das aktuelle Jahr sondern die Differenz des aktuellen Jahres zum Jahr 1900. Also z.Bsp. nicht 2002 sondern 102.

Lösungsvorschlag:
jahr = Date.getYear();
jahr += (jahr<1000) ? 1900 : 0;

eingeschränkte Parameterübergabe
betrifft: 6.xx

Ein im Opera geladenes JavaScript kann den Inhalt der URL des gerade geladenen Dokuments, sowie die darin möglicherweise für das Skript übergebenen Parameter nur dann lesen, wenn das Skript direkt im Dokument selbst steht. Wird das gleiche Skript aus einer Datei über das Attribut SRC (eng. source = Quelle)  des SCRIPT-Tags importiert liefert Opera als Ergebnis den leeren String zurück.

Speicherproblem bei Skripten
betrifft: 4.xx  (beseitigt in 6.xx)

Im Netscape Navigator, bzw. Communicator gibt es einen Fehler bei der Speicherbelegung. Dieser tritt aber nur beim allerersten Dokument oder Frameset auf, das nach dem Start des Navigators geladen wird. Für dieses Dokument wird nicht genügend Speicher bereitgestellt. Daher werden Skripte, die eine gewisse Länge überschreiten nicht mehr ausgeführt.

Lösungsvorschlag:
Sie können diesen Fehler elegant umgehen, indem sie einfach eine Startseite ohne JavaScript VOR ihrer eigentlichen Webseite einbinden. Über einen Meta-Refresh können sie ihre Besucher dann bequem weiterleiten. Es muss sich aber um ein Einzeldokument handeln und die Website muss als ganze Seite (target="_top") geladen werden, da nur so der Navigator wirklich eine Aktualisierung vornimmt.
<HEAD>
<BASE TARGET="_top">
<META HTTP-EQUIV="Refresh" CONTENT="0; URL=http://meineWebseite.de">
</HEAD>

Größe von Bildern
betrifft: 6.xx

Der Opera-Browser hat eine gravierende Beschränkung was Bilder angeht. So ist es im Opera weder möglich die Eigenschaften "width" und "height" (eng. "Breite" und "Höhe") zu schreiben (was im Netscape 4.xx ebenfalls der Fall ist) noch diese zu lesen. Wird auf diese Werte zugegriffen, liefert Opera stets "0" als Ergebnis.

Lösungsvorschlag:
Wenn sie für den Opera z.Bsp. eine Bildergalerie erstellen wollen, müssen sie die Breite und Höhe der Bilder explizit im HTML definieren und darauf achten, dass alle Bilder die gleiche Größe haben. Alternativ können sie ein Skript schreiben, dass ihr HTML-Dokument erzeugt, müssen dann aber die Größen der Bilder von Hand im Skript definieren (was nicht gerade viel besser ist).

Fehler bei Number-Objekt
betrifft: 4.xx  (beseitigt in 6.xx) 5.xx  (beseitigt in 6.xx)

Im Netscape Navigator funktionierte die Funktionen Number.parseInt() Number.parseFloat() NumberisNaN() auf einigen Plattformen nicht. Im Internet Explorer waren sie lediglich integriert, hatten aber keine Funktion. Insbesondere liefert der Test isNaN() (prüft, ob der angegebene Wert KEINE Zahl ist) immer den Wert "false". Der spezielle Wert "NaN" (eng. not a number = keine Zahl) ist im Internet Explorer nicht verfügbar. Strings, die keine Zahlen sind, werden stattdessen zu der Zahl 0.

Lösungsvorschlag:
Wenn sie Strings in normalen Gleichungen verwenden, werden diese automatisch in Zahlenwerte umgewandelt. Also: "9.100" wird zu 9,1 usw.
Wenn sie bestimmen wollen, ob es sich wirklich um eine Zahl handelt, verwenden sie die folgende Funktion. Sie liefert "true" zurück, wenn es sich nicht um eine Zahl handelt und "false" sonst.
function isNotANumber(string) {
 if (string.match(/^[+-]?[\.\d]*$/)) {
   return false;
 } else {
   return true; };
};

Sollten sie noch nie einen regulären Ausdruck in JavaScript gesehen haben, wirkt diese Funktion auf sie vielleicht etwas kryptisch - vertrauen sie mir: es sieht zwar kompliziert aus, aber es funktioniert ;) 

Höhe von I-Frames
betrifft:  6.xx (beseitigt in 6.2)

Der Netscape Navigator hat einen Bug, was das Attribut "height" des Tags IFRAME angeht. Der hier angegebene Wert wird ignoriert. IFRAMEs sind damit zwar im Netscape 6 integriert, richtig funktionieren tun sie jedoch erst seit Kurzem.

Speicherleck bei setTimeout()
betrifft: 

Die Funktion window.setTimeout() erzeugt leider ein Speicherleck bei allen bekannten Browsern. Sie fordert bei jedem Aufruf Speicher an. Allerdings wird dieser anschließend nicht wieder freigegeben. Wenn sie z.Bsp. eine Funktion verwenden, die sich über setTimeout() zyklisch selbst aufruft (wie zum Beispiel ein Newsticker)  kann diese den Browser auf Dauer bremsen oder sogar zum Absturz bringen.
Gehen sie deswegen sparsam mit dieser Funktion um.

Fehler bei CSS 2.0
betrifft:  5.xx  (beseitigt in 6.xx) 6.xx (beseitigt in 7.xx) 6.xx

Die Positionierung von Layern über "z-index" funktioniert in den genannten Versionen trotz der prinzipiellen Unterstützung von CSS 2.0 nur eingeschränkt. Das betrifft insbesondere I-Frames. I-Frames sind aus dem attraktiven Layermodell ausgeschlossen und werden immer im Vordergrund dargestellt, selbst wenn ihnen ein anderer "z-index" (= Höhe des Layers) zugewiesen wird.

CSS: Rahmen bei Bildern
betrifft:  4.xx (beseitigt in 6.xx)

Wird über CSS für ein Bild (IMG-Tag) ein Rahmen festgelegt und ist im Tag selbst gleichzeitig "BORDER=0" (kein Rahmen) gesetzt führt das zu Darstellungsfehlern im Netscape 4. Dies betrifft übrigens auch Bilder oder Buttons, für die mit der CSS-Anweisung "cursor" ein alternativer Mauscursor festgelegt wurde. Sie sollten diese CSS-Anweisungen in Verbindung mit IMG-Tags daher versuchen zu vermeiden.

Sicherheitslücke in JScript
betrifft:  6.xx

Der Microsoft-Ableger von JavaScript: JScript hat eine Sicherheitslücke, die es möglich macht, über die Funktion "document.execScript()" auf ihrer Festplatte gespeicherte Dateien und via "document.execCommand()" Systemvariablen, wie den Inhalt der Zwischenablage zu lesen. Dies war im Test trotz 2 aktiver Firewalls (ZoneAlarm 2.6 und Outpost 1.0) problemlos möglich.

Wie der Datenklau genau funktioniert lassen wir hier einmal offen.

Lösungsvorschlag:
Das ist ein Fall für ein Update, entweder des IE oder ihrer Firewall. Schneller beseitigen können sie dieses Problem allerdings auch, wenn sie ein Programm zum Filtern von Inhalten (meist Bestandteil einer Firewall oder Kindersicherung) ihr Eigen nennen. In diesem Fall geben sie an, dass Seiten welche die Zeichenfolgen "execScript(" oder "execCommand(" enthalten nicht angezeigt werden sollen. Damit sind sie vorerst vor bösen Überraschungen sicher.

Java 1.2 nicht unterstützt
betrifft:  6.xx

Der Internet Explorer nutzt für die Interpretation von Java-Applets (Java: ist nicht gleich JavaScript!) nicht etwa die Original JVM (Abk. = Java Virtual Machine) von Sun sondern ein von Microsoft entwickeltes Plagiat das bei weitem nicht an die eigentlich gewünschte Qualität heranreicht. Nebeneffekt des Ganzen: Java 1.2 wird vom Internet Explorer 6 noch nicht unterstützt. Sind beide Versionen (Original und "Fälschung") installiert, verwendet IE bevorzugt die veraltete Microsoftfassung.
Fazit: verzichten sie wenn möglich auf den Einsatz von Java 1.2 bei ihren Applets.

 

Bug bei Pattern-Match
betrifft: 5.xx  (beseitigt in 6.xx)

Die regulären Ausdrücke sind im Internet Explorer unvollständig umgesetzt. Ein Quantifier (*,+,? etc.) darf nicht von einem zweiten gefolgt werden. Der Ausdruck ".*?" ist beispielsweise nicht erlaubt und löst eine Skriptfehler aus, obwohl es sich dabei um einen syntaktisch korrekten regulären Ausdruck handelt.

Erläuterung: Seit JavaScript 1.2 ist die Verwendung von regulären Ausdrücken und Mustervergleichen erlaubt. Dabei gibt es seit jeher einige Verwirrung um den Ausdruck ".*".  Der Punkt steht dabei für "ein beliebiges Zeichen" und der Quantifier Stern steht für "beliebig oft". Allerdings findet der reguläre Ausdruck ".*a" eben nicht das erste Vorkommen des Buchstaben "a" sondern das Letzte. Um dagegen das erste Vorkommen des Buchstabens zu finden muss der Ausdruck lauten ".*?a". Dies führt im Internet Explorer 5 aber zu einem Skriptfehler.

Beschränkung der Länge der URL
betrifft: systemabhängig

Abhängig von der Art des verwendeten Systems kann die Anzahl der Stellen, die eine aufgerufene URL haben darf variieren. Das hat einen Einfluss auf übergebene Parameter. Ist die URL (inklusive dieser Parameter) zu lang, werden alle überstehenden Zeichen einfach gelöscht.

Lösungsvorschlag:
/* Alternative Übergabe von Skriptparametern. Zunächst öffnen wir die Zielseite: */
seite = window.open("neu.html", "ziel");
/ jetzt geben wir der neuen Seite die Parameter mit.  */
seite.parameter1 = ...;
seite.parameter2 = ...;
/* das Skript, innerhalb unseres neuen Fenster kann die Parameter als Eigenschaften des window-Objekts abrufen: also paramter1 = window.parameter1 usw. */

Fehler bei document.write()
betrifft:  4.xx (beseitigt in 6.xx) 6.xx

Dies betrifft HTML-Seiten, die dynamisch über JavaScript erzeugt werden sollen.
Insbesondere der Opera-Browser hat die besondere Begabung, Programmierer hier fast in den Wahnsinn zu treiben, denn wenn eine solche Seite im Netscape 4 endlich funktioniert (was allein schon an ein Wunder grenzt) funktioniert sie garantiert im Opera nicht - und umgekehrt.
Prinzipiell können beide Browser nur ein bestehendes Dokument überschreiben, aber kein komplett neues erzeugen. Und das auch nur dann, wenn es sich um ein Dokument handelt, dass nicht etwa über einen HTML-Link, sondern über ein JavaScript geöffnet wurde. Die Funktion document.open() ist im Opera außerdem fehlerhaft und funktioniert nicht richtig. Verwenden sie statt dessen document.clear().

Lösungsvorschlag:
/* selbst das funktioniert leider nicht immer! */
seite = window.open("", "ziel");
seite.document.clear();
seite.document.write(...);
seite.document.close();
/* manchmal müssen sie für den Opera bei window.open() eine (echte) leere Datei als Dummy angeben ... */

Größenveränderung des Fensters
betrifft: 4.xx  (beseitigt in 6.xx)

Netscape 4 lädt die aktuell anzeigte Seite neu, sobald der User die Größe des Fensters verändert. Globale Variablen von laufenden JavaScripts werden dabei allerdings gelöscht. Die evtl. auf der Seite enthaltenen Skripte werden nicht neu interpretiert. Dies kann ein laufendes Skript natürlich zum Absturz bringen.

Lösungsvorschlag:
Hier kann man wirklich nicht viel tun, außer sehr vorsichtig zu programmieren. Prüfen sie beim Aufruf einer globalen Variablen stets zuvor, ob diese noch existiert. Wenn nicht müssen sie diese Variablen reinitialisieren. Mit Scriptmitteln lässt sich der Bug nicht beseitigen, es sei denn sie verbieten dem User die Größe der Seite zu verändern. Dazu müssen sie ihn die Seite über folgenden Link öffnen lassen:
<A HREF="dokument.html" TARGET="zielframe" ONCLICK="window.open('dokument.html', 'zielframe', 'resizable=0')">hier klicken!</A>

Fehler im JavaScript-Interpreter
betrifft:  6.xx  (beseitigt in 7.xx)

Der JavaScript-Interpreter des Opera 6 steckte seiner Zeit noch in den Kinderschuhen. Nicht nur dass der Interpreter der alten Version schleichend langsam ist, er ist auch sehr empfindlich. Werden im Opera 6 mehrere JavaScripts gestartet während bereits ein anderes Skript ausgeführt wird, kann dies in einigen Versionen den Browser komplett zum Absturz bringen. Hierfür gibt es leider keine Skriptlösung, es sei denn sie nehmen dem System die Kontrolle über die Skriptprozesse aus der Hand, indem sie eine globale Variable definieren die jedes Skript beim Start setzt und wieder annulliert, wenn es fertig ist. Ein zweites Skript könnte nun feststellen, dass bereits ein Skript läuft und die Ausführung über den Aufruf window.setTimeout("meineFunktion()", 1000); einfach verschieben. Andernfalls müssen sie Operanutzer einfach bitten, entweder eine neuere Version zu benutzen, oder nicht zu schnell zu klicken, damit ihr Browser nicht überfordert ist. ;)

Betreten einer Seite
betrifft:  4.xx (beseitigt in 6.xx)

Das Ereignis onLoad des BODY-Tags feuert im Netscape 4 zu früh. Nämlich auch dann, wenn das Laden der Seite noch gar nicht abgeschlossen ist. Daher kann es in diesem Browser nicht verwendet werden, um festzustellen wann der Ladevorgang abgeschlossen ist. Das heißt auch, dass der Aufruf einer Funktion über onLoad im Navigator 4 eventuell scheitert, weil die Funktion (da das entsprechende Skript noch nicht geladen ist) gar nicht definiert ist.
Schreiben sie stattdessen einfach den Aufruf in einen SCRIPT-Tag, den sie am Ende der Seite platzieren oder zumindest hinter die Funktion oder das Element, welches sie im Skript verwenden wollen.

Verlassen einer Seite
betrifft:  4.xx (beseitigt in 6.xx)

Das Ereignis onUnload des BODY-Tags ist im Netscape 4 leider fehlerhaft. Wird hier z.Bsp. ein Hinweisfenster geöffnet, kann dies den Absturz des Browsers zur Folge haben. Versuchen sie daher auf die Verwendung dieses Ereignisses zu verzichten.

Problem mit .innerHTML
betrifft:  7.xx

Netscape 7 kann (im Gegensatz zum Vorgänger) mit der Eigenschaft ".innerHTML" nicht korrekt umgehen. Wenn der HTML-Inhalt eines Tags (also alles zwischen dem öffnenden und dem dazugehörigen schließenden Tag) ersetzt wird und sich innerhalb des Tags ein weiterer Tag befindet, wird dieser bevor der Inhalt ersetzt wird erneut interpretiert. Das ist normalerweise nicht weiter tragisch, hat aber dramatische Folgen, wenn es sich bei diesem Inhalt um ein Skript handelt.

Lösungsvorschlag:
Es gibt leider nur eine Lösung - widerstehen sie der Versuchung, über die Eigenschaft "innerHTML" Skriptinhalte in HTML-Tags zu ersetzen. Achten sie bei ihren Skripten also darauf, dass der ersetzte Inhalt keine automatisch interpretierten Skriptelemente enthält.

JavaScript-Konsole in Netscape 7
betrifft:  7.xx

Netscape hat in Version 7 eine neue JavaScript-Konsole für Webentwickler eingebaut, die - wenn aktiviert - jeden Aufruf protokolliert. Ergebnis: bei aktivierter Konsole ist der JavaScript-Interpreter jetzt so langsam, dass sie sich bequem zwischenzeitlich einen Kaffee holen können, bis sich eine komplexe Internetseite mit JavaScript aufgebaut hat. Dieses Tool ist nur für Entwickler zur Evaluation gedacht und nicht für den Normalbetrieb im Internet. Ergo: Nutzer des Browsers sollten beim Surfen die Konsole stets deaktivieren!

neuere CSS-Standards fehlen
betrifft: 6.xx

Weil es seit geraumer Zeit für den Internet Explorer keine Aktualisierungen auf den neuesten Standard des W3C mehr gegeben hat, werden eine Reihe von neueren CSS-Kommandos ab CSS 2.1, im Internet Explorer nicht unterstützt. Dies betrifft unter anderem folgende Anweisungen:

Beispiele:
1) den Wert "inherit" in allen bisher bekannten Fällen
2) die Anweisung position: "static"
3) die Anweisung content:
4) die Pseudoklassen :before und :after
5) alle Attributzugriffe wie zum Beispiel a[href=about:blank] { ... }
6) die Anweisung(en) counter-increment/counter-reset usw.
sowie weitere.