Journal

Das Wort, das fehlte

Acht Stellen auf elchi.dev zeigten nichts, wo ein Wort hingehörte; ohne JavaScript schrieben beide Formulare Personendaten in die URL. Der Build stoppt beides.

An acht Stellen auf elchi.dev stand nichts, wo ein Wort hingehörte. Die Zeile unter unserem Namen im Footer jeder Seite war eine davon. Die Kontaktseite hatte keine Beschriftung für ihre Themenliste. Niemand hat es bemerkt, denn ein leeres Element sieht nicht kaputt aus. Es sieht aus wie nichts.

Der Build weigert sich jetzt, eine Seite zu erzeugen, die einen Text verlangt, den es nicht gibt. Und die zwei Formulare der Website, die etwas absenden, funktionieren ohne JavaScript. Das taten sie vorher nicht.

Wie ein Wort verloren geht

Die Texte auf elchi.dev liegen in einem Katalog, einer pro Sprache, bearbeitet in unserem Dashboard. Eine Seite verlangt einen Text über seinen Schlüssel, etwa contact.topic_label, und der Build setzt die Wörter ein. Gab es einen Schlüssel nicht, renderte das Template stillschweigend einen leeren String. Kein Fehler, keine Warnung.

Eine Prüfung hatten wir. Sie verglich den deutschen Katalog mit dem englischen und liess den Build scheitern, wenn ein Schlüssel im einen existierte und im anderen nicht. Das findet eine vergessene Übersetzung. Einen Schlüssel, der in beiden fehlt, findet es nicht, und genau das war passiert: Sechs Schlüssel, die die Seiten nutzten, waren in keiner Sprache je geschrieben worden. Zwei weitere waren Tippfehler von Schlüsseln, die es gab.

Ein leerer Absatz schadet niemandem, der hinschaut. Eine leere legend schadet sehr wohl jemandem mit Screenreader: Sie ist der Name einer Gruppe von Auswahlmöglichkeiten, und ohne sie waren die Themen im Kontaktformular eine Gruppe ohne Namen.

Was der Build jetzt tut

Die Seiten lesen den Katalog über einen strikten Lookup. Wer einen Schlüssel verlangt, den es nicht gibt, stoppt den Build, und die Meldung nennt den Schlüssel und sagt, wo er hinzuzufügen ist. Beim ersten Lauf fand er einen weiteren: Die 404-Seite verlangte einen Linktext, den es nie gegeben hatte, und überdeckte das mit einem Fallback, der im Template stand.

Das Deploy-Skript prüft das Ergebnis ebenfalls. Eine Seite mit leerer Überschrift wies es schon vorher ab. Jetzt weist es auch einen Build ab, der einen leeren Absatz, ein leeres Label, eine leere Legend, einen leeren Listenpunkt, einen leeren Eintrag einer Beschreibungsliste, einen leeren Link, Button oder eine leere Hervorhebung enthält, ausserdem einen leeren span, ausser er ist als Dekoration ausgewiesen. Der strikte Lookup findet einen fehlenden Schlüssel; diese Prüfung findet alles andere, was nichts rendert.

Die Formulare, ohne JavaScript

Das Kontaktformular und der Konfigurator werden von einem Skript abgeschickt, das neben jedem Feld antwortet und die Seite nie verlässt. Dieser Teil funktionierte. Das Problem war, was ohne Skript geschah.

Keines der beiden Formulare gab an, wie es gesendet werden soll, und ein Formular ohne Angabe wird als GET gesendet. Ein Browser ohne JavaScript schrieb also Name, E-Mail-Adresse und die ganze Nachricht in die Adresszeile. Von dort landet das im Browserverlauf, in Serverlogs und in allem anderen, was Adressen aufzeichnet. Dass JavaScript ausgeschaltet ist, kommt selten vor, aber wenn, dann sind genau das die Daten, die dort nicht landen sollen.

Beide Formulare geben jetzt method="post" an und gehen an denselben Endpoint, den das Skript nutzt. Ohne Skript prüft der Browser die Pflichtfelder selbst, und der Server antwortet mit einer Seite: einem Dank oder einer Seite, die sagt, was das Formular braucht, und den Weg zurück anbietet, zusammen mit unserer E-Mail-Adresse und Telefonnummer.

Eines lässt sich nicht übertragen. Mit Skript hält das Formular fest, wann es auf dem Bildschirm erschien, und eine Anfrage, die weniger als zwei Sekunden später eintrifft, gilt als Bot. Ohne Skript gibt es diesen Zeitstempel nicht, also entfällt diese Prüfung. Das versteckte Feld, das nur Bots ausfüllen, greift weiterhin, ebenso die Regel, dass eine Nachricht mit mehr als vier Links Spam ist.

Der Punkt

Eine statische Website ist schnell, weil sie aus einfachen Dateien besteht. Einfache Dateien tun auch genau das, was in ihnen steht, auch nichts, und zwar ohne sich zu beschweren. Die Prüfungen sind dazu da, „nichts“ laut zu machen.

Quellen

  1. HTML Standard: form submission attributes, WHATWG, gelesen am
  2. Understanding Success Criterion 1.3.1: Info and Relationships, W3C, gelesen am

Geschrieben von Samuel Krauss, Founder. Abgelegt unter website, accessibility, forms.

Übersetzt aus dem Englischen. Zum englischen Original

Alle Beiträge Dieser Beitrag als Markdown Atom-Feed