Zum Inhalt springen
DSGVO-konform. Gehostet in DE.
14 Tage kostenlos testen →
MonitoringZeichenkodierungMigration
Monitoring 13 Min. Lesezeit 25. Sept. 2026

Zeichensalat nach dem Umzug: Kodierung richtig prüfen

Nach Serverwechsel, Datenbankumzug oder Systemwechsel zeigen Seiten plötzlich Grüße statt Grüße. Wo die Kodierung entschieden wird, welche Angabe Vorrang hat und wie sich der Zustand nach der Umstellung messen lässt.

X

XICTRAQ

XICTRAQ

MonitoringSEOPerformance
1024 Bytes
in denen die Kodierungsangabe eines HTML-Dokuments vollständig stehen muss (HTML Living Standard)
1 bis 4 Bytes
belegt ein Zeichen in UTF-8, je nach Codepunkt (RFC 3629)
3 Bytes
Höchstlänge je Zeichen im Zeichensatz utf8mb3, vier erst in utf8mb4 (MariaDB)
Die Kette der ZeichenkodierungFünf Stellen entscheiden, wie ein Sonderzeichen beim Leser ankommt1 Speicherutf8mb42 VerbindungSET NAMES3 HTTP-Kopfcharset=utf-84 Dokumentmeta charset5 BrowserAnzeigeVorrang bei widersprüchlichen Angaben1. Byte Order Mark2. HTTP Content-Type3. meta charset4. Rückfall windows-1252Wie derselbe Text beim Leser ankommtInhalt im DatenbestandAusgabe ohne KodierungsangabeAusgabe mit charset=utf-8GrüßeGrüßeGrüßeÖffnungszeitenÖffnungszeitenÖffnungszeiten39,90 €39,90 €39,90 €Vorrangregel und 1024-Byte-Grenze: HTML Living Standard, Abschnitte 4.2.5.4 und 13.2.3Kodierungsangabe innerhalb von1024 Bytes (HTML Living Standard)UTF-8 je Zeichen1 bis 4 Oktette (RFC 3629)Zeichensatz utf8mb3höchstens 3 Bytes (MariaDB)
Ein Serverumzug, eine Datenbankmigration oder ein Wechsel des Redaktionssystems ändert selten das Layout, häufig aber die Zeichenkodierung. Das Ergebnis steht dann als „Grüße“ oder „Öffnungszeiten“ in Produkttexten, Formularbeschriftungen und Dateinamen, während Startseite und Menü sauber aussehen. Die Verfügbarkeitsprüfung meldet weiterhin Statuscode 200, die Ladezeit bleibt unverändert, ein Sicherheitsscan findet nichts. Der Schaden ist trotzdem kaufmännisch: unlesbare Preisangaben, Suchergebnisse ohne Treffer, falsch einsortierte Formulardaten. Dieser Beitrag beschreibt, an welchen Stellen eine Zeichenkodierung überhaupt festgelegt wird, welche Angabe bei Widerspruch Vorrang hat, woran sich die Fehlerart am Zeichenbild ablesen lässt und wie sich der Zustand nach einem Umzug messen statt erraten lässt.

Warum der Zeichensalat erst nach dem Umzug sichtbar wird

In einer Datei steht kein Text, sondern eine Folge von Bytes. Welche Zeichen daraus werden, entscheidet erst die Kodierung, mit der jemand diese Bytes liest. UTF-8 kodiert Zeichen aus dem Bereich U+0000 bis U+10FFFF in Folgen von einem bis vier Oktetten (RFC 3629); ein „ü“ (U+00FC) belegt darin zwei Bytes, ein „€“ (U+20AC) drei. Wer dieselben Bytes mit einem Einzelbyte-Zeichensatz liest, bekommt für jedes dieser Bytes ein eigenes Zeichen, und aus einem „ü“ werden zwei sichtbare Zeichen. Genau das ist der Zeichensalat. Die Bytes sind dabei in der Regel unverändert; falsch ist die Anweisung, wie sie zu lesen sind.

Vor dem Umzug hat diese Anweisung meistens gestimmt, ohne dass sie jemand ausdrücklich festgelegt hätte. Der alte Webserver setzte eine Vorgabe, die alte Datenbank eine dazu passende, und das Ergebnis sah richtig aus. Ein Umzug ersetzt genau diese stillschweigenden Vorgaben: eine andere Voreinstellung im Webserver, ein anderer Standardzeichensatz in der Datenbank, ein Ausgabefilter, der beim Export eine andere Annahme trifft. Der Bruch tritt deshalb selten überall gleichzeitig auf. Betroffen ist zuerst, was aus der Datenbank kommt, während statisch hinterlegte Menütexte unverändert bleiben. Die Startseite wirkt darum oft unauffällig, obwohl mehrere hundert Detailseiten es nicht sind. Was bei einem Umzug sonst noch messbar auseinanderläuft, beschreibt der Beitrag Website-Migration überwachen.

  • 1 bis 4 Oktette belegt ein Zeichen aus dem Bereich U+0000 bis U+10FFFF in UTF-8 (RFC 3629).
  • 1024 Bytes ist die Grenze, innerhalb der die Kodierungsangabe eines HTML-Dokuments vollständig stehen muss (HTML Living Standard).
  • Genau eine meta-basierte Kodierungsangabe je Dokument ist zulässig (HTML Living Standard).
  • windows-1252 empfiehlt der Standard als Rückfallkodierung für alle Sprachumgebungen, die in seiner Tabelle nicht eigens genannt sind; normativ bleibt der Rückfall implementierungsabhängig (HTML Living Standard).
  • U+FFFD ist das Ersatzzeichen, das ein Dekodierer im Fehlermodus „replacement“ für ungültige Bytefolgen ausgibt (Encoding Standard).
  • Ein bis drei Bytes je Zeichen speichert der Zeichensatz utf8mb3, vier Bytes für ergänzende Zeichen erst utf8mb4 (MariaDB-Dokumentation).

Diese Werte stammen aus Normtexten und aus der Dokumentation einer quelloffenen Datenbank, nicht aus einer Erhebung. Sie sagen deshalb nichts darüber, wie häufig ein Fehler auftritt, sondern nur, was gelten soll und welche Grenzen die beteiligten Bausteine haben. Für die Fehlersuche ist das die nützlichere Sorte Zahl, weil sie an jedem Einzelfall nachprüfbar ist. Wie viele Adressen im eigenen Bestand betroffen sind, beantwortet dagegen erst eine Messung über den ganzen Bestand, und die ist der eigentliche Gegenstand dieses Beitrags.

Die Kette: fünf Stellen, an denen eine Kodierung festgelegt wird

Zwischen dem gespeicherten Byte und dem angezeigten Zeichen liegen mehrere Stellen, an denen eine Kodierung festgelegt oder angenommen wird. Erstens der Speicher: Zeichensatz und Sortierregel der Datenbankspalte. Zweitens die Verbindung zwischen Anwendung und Datenbank, die eine eigene Kodierung aushandelt. Drittens die Anwendung selbst, samt der Kodierung ihrer Vorlagendateien. Viertens der Transport, also das Kopffeld Content-Type der HTTP-Antwort. Fünftens das Dokument mit seiner eigenen Angabe. Stimmen alle fünf überein, ist der Fall langweilig. Ein Umzug ändert erfahrungsgemäß zwei oder drei davon, und übrig bleibt eine Kette, in der eine Stelle etwas anderes behauptet als die übrigen.

Das Kopffeld der HTTP-Antwort ist die Stelle, die nach einem Serverwechsel besonders oft anders aussieht als vorher. RFC 9110 legt fest, dass ein Absender, der Inhalt mitsendet, ein Content-Type-Kopffeld erzeugen sollte, sofern ihm der beabsichtigte Medientyp bekannt ist (RFC 9110, Abschnitt 8.3); derselbe Abschnitt hält fest, dass Betreiber ihre Ursprungsserver in der Praxis nicht durchgängig korrekt konfigurieren (RFC 9110). Ein Content-Type ohne charset-Angabe ist zulässig und trotzdem folgenreich, weil die Entscheidung dann eine Stufe tiefer fällt. Ein Content-Type mit falscher charset-Angabe ist der unangenehmere Fall, denn er gewinnt gegen die Angabe im Dokument.

Eine Kodierungsangabe wandelt nichts um

Die Angabe im Kopffeld oder im Dokument beschreibt, wie die gelieferten Bytes zu lesen sind. Sie verändert die Bytes nicht. Wer bei kaputter Anzeige die Angabe von utf-8 auf einen Einzelbyte-Zeichensatz umstellt, damit es wieder richtig aussieht, hat den Fehler nicht behoben, sondern eingefroren: Der Datenbestand bleibt, wie er ist, und jede weitere Verarbeitung — Suche, Export, Schnittstelle, Rechnungsdokument — arbeitet weiter mit der falschen Annahme.

Vorrang: welche Angabe gewinnt, wenn zwei sich widersprechen

Der HTML Living Standard beschreibt als eigenes Verfahren, in welcher Reihenfolge die Kodierung eines Dokuments bestimmt wird. Für die Fehlersuche zählt vor allem, dass diese Reihenfolge feststeht und dass die früheren Stufen die späteren überstimmen.

  1. Byte Order Mark: Beginnt der Bytestrom mit einer BOM, wird das übergebene Kodierungsargument ignoriert und die BOM selbst übersprungen (HTML Living Standard). Eine BOM in einer Programmdatei erzeugt außerdem Ausgabe vor dem ersten Kopffeld, also einen zweiten, davon unabhängigen Fehler.
  2. Vorgabe der Nutzerseite: Hat jemand im Browser eine Kodierung erzwungen, darf das Programm diese Kodierung zurückgeben; im Standard steht dieser Schritt nach der BOM-Prüfung und ist als Kann-Schritt formuliert (HTML Living Standard). Er erklärt, warum eine Seite auf einem einzelnen Arbeitsplatz richtig und auf allen anderen falsch aussieht.
  3. Transportschicht: Gibt die Transportschicht eine unterstützte Kodierung an, wird diese mit der Zuversicht „certain“ zurückgegeben (HTML Living Standard). Das ist die charset-Angabe im Content-Type.
  4. Vorabprüfung des Dokuments: Erst danach wird das Dokument selbst betrachtet. Die Autorenvorgaben begrenzen Kodierungsangaben auf die ersten 1024 Bytes, und Browser sind angehalten, genau diesen Bereich vorab zu prüfen (HTML Living Standard).
  5. Rückfall: Bleibt alles offen, greift eine vorgegebene Standardkodierung, die von der Sprachumgebung abhängt; für alle nicht eigens genannten Umgebungen steht dort windows-1252 (HTML Living Standard).

Aus dieser Reihenfolge folgt der Befund, der nach einem Serverumzug besonders oft vorliegt: Im Dokument steht die richtige Angabe, im Kopffeld die falsche, und die Anzeige richtet sich nach dem Kopffeld. Die Angabe im Dokument ist deshalb keine Absicherung gegen eine falsche Angabe im Kopf, sondern nur die Auffanglinie für den Fall, dass gar keine charset-Angabe gesendet wird. Umgekehrt gilt: Wer die Grenze von 1024 Bytes überschreitet, etwa weil vor dem Kopfbereich ein langer Kommentar, eine Einwilligungsschicht oder ein eingebettetes Skript steht, verliert die Angabe im Dokument stillschweigend. Der Standard erlaubt zudem genau eine meta-basierte Angabe je Dokument (HTML Living Standard); zwei widersprechende Angaben sind kein Sicherheitsnetz, sondern ein Fehler.

Der Kopf schlägt das Dokument

Vor jeder Änderung am Dokument gehört das Kopffeld gemessen. Ein Content-Type: text/html ohne charset verhält sich anders als Content-Type: text/html; charset=iso-8859-1, und beide sehen im Browserfenster gleich falsch aus. Der Unterschied entscheidet aber darüber, ob die Reparatur in die Serverkonfiguration gehört oder in die Vorlage. Messen Sie deshalb zuerst den Kopf, dann die ersten 1024 Bytes, dann den Datenbestand — in dieser Reihenfolge.

Fehlerbilder: was das Zeichenbild über die Ursache verrät

Der Zeichensalat hat wenige, gut unterscheidbare Formen. Wer das Bild richtig einordnet, spart den Umweg über die Vermutung. Entscheidend ist die Frage, ob der Schaden nur in der Anzeige liegt oder bereits im gespeicherten Byte.

ZeichenbildUrsacheWo repariert wird
Grüße auf der SeiteUTF-8-Bytes werden als Einzelbyte-Zeichensatz gelesenKopffeld und Dokumentangabe angleichen
Grüße im Browser, Grüße im ExportAnzeige stimmt, der Bestand ist doppelt kodiertDatenbestand, nicht die Anzeige
Ersatzzeichen mitten im Wortungültige Bytefolge, U+FFFD eingesetztRückweg auf den Stand vor der Umkodierung
GrüßeText wurde zweimal nach UTF-8 umkodiertMigrationsschritt wiederholen, nicht nachbessern
Ziffernfolgen mit Rautezeichen im gespeicherten TextZeichenreferenzen aus einem Formular wurden als Text gespeichertEingabepfad und Formularkodierung

Zwei dieser Zeilen verdienen eine Begründung. Die dritte ist der einzige Fall, in dem die Information tatsächlich fort ist: Der Encoding Standard schreibt für den Fehlermodus „replacement“ vor, dass ein Dekodierer bei einer ungültigen Bytefolge U+FFFD ausgibt (Encoding Standard). Aus dem Ergebnis lässt sich das ursprüngliche Byte in der Regel nicht zurückrechnen, weil verschiedene fehlerhafte Folgen dasselbe Ersatzzeichen ergeben. Die vierte Zeile ist der Fall, den eine zweite Reparatur verschlimmert: Wer doppelt kodierten Text noch einmal umkodiert, erzeugt eine dritte Lage. Der Rückweg führt hier über den Stand vor der Migration, nicht über einen weiteren Durchlauf.

Was eine Prüfung nach dem Umzug tatsächlich messen muss

Eine Statusampel beantwortet die Frage nach der Zeichenkodierung nicht. Statuscode 200, unveränderte Ladezeit und ein gültiges Zertifikat sind mit vollständig unlesbaren Produkttexten vereinbar; Uptime-Monitoring ist die Grundlinie, nicht die Antwort. Gemessen werden muss der Inhalt selbst, und zwar über den ganzen Bestand statt an drei Stichproben, denn der Fehler sitzt gerade dort, wo selten jemand hinsieht.

Textvergleich Stand für Stand

Die Screenshot- und Änderungsüberwachung hält je Adresse den vorherigen Textstand vor und meldet, wenn sich das Zeichenbild ändert. Ein Bruch, der viele Seiten gleichzeitig betrifft, fällt in dieser Ansicht als Muster auf und nicht als Einzelfall.

Titel und Beschreibung im Blick

SEO-Monitoring prüft Titel, Beschreibung und strukturierte Daten. Genau dort wird der Zeichensalat für Besucher zuerst sichtbar, weil Suchergebnisse und geteilte Vorschauen aus diesen Feldern gebaut werden.

Eingabewege im echten Browser

Browser-Monitoring durchläuft Formular, Suche und Warenkorb. Fehler, die erst beim Absenden eines Feldes mit Umlauten entstehen, zeigen sich auf diesem Weg und nicht im Abruf der Startseite.

Meldung an jemanden, der sie annimmt

Die Alarmierung verteilt den Befund über zwei Kanäle und eskaliert, wenn niemand annimmt. Ein Kodierungsfehler ist selten dringend im Sinne eines Ausfalls, aber teuer, wenn er drei Wochen unbemerkt steht.

Ergänzend gehört in dieses Bild, was sich zwischen zwei Ständen überhaupt verändert hat. Ein Bildabgleich zeigt den Bruch dort, wo er im Layout auffällt; wie das Verfahren arbeitet und wo seine Grenzen liegen, beschreibt der Beitrag Website-Änderungen per Bildvergleich erkennen. Für den Textteil ist der Beitrag Content-Änderungen erkennen einschlägig, weil er dieselbe Frage aus der Richtung unbefugter Änderungen stellt.

Selbst nachmessen: vom Kopffeld bis zum Byte

Die Messung braucht keine besondere Ausstattung. Drei Abrufe grenzen den Fehler auf eine Schicht ein, und sie tun das in derselben Reihenfolge, in der auch ein Browser entscheidet.

$ curl -sSI https://www.example.invalid/produkte/gruesse | grep -i '^content-type'
content-type: text/html
$ curl -sS https://www.example.invalid/produkte/gruesse | head -c 1024 | grep -io 'charset=[a-z0-9-]*'
charset=utf-8
$ curl -sS https://www.example.invalid/produkte/gruesse | grep -c 'Ã'
23

Der erste Abruf zeigt den Fall, der nach einem Serverwechsel oft vorliegt: ein Content-Type ohne charset-Angabe. Damit fällt die Entscheidung eine Stufe tiefer, und der zweite Abruf beantwortet, ob dort überhaupt etwas steht und ob es innerhalb der ersten 1024 Bytes steht, denn nur dieser Bereich zählt (HTML Living Standard). Der dritte Abruf zählt ein Zeichen, das in deutschem Fließtext praktisch nicht vorkommt und in fehldekodiertem UTF-8 in fast jedem Umlaut steckt. Eine Zahl deutlich über null ist ein starker Hinweis; null ist kein Freispruch, weil ein Bestand auch Ersatzzeichen enthalten kann.

zeichenbild.py
# Ordnet eine gelieferte Bytefolge ein: sauber, fehldekodiert oder verloren
SPUREN = ("Ã", "Â", "â€", "")

def einordnen(rohbytes: bytes) -> str:
    try:
        text = rohbytes.decode("utf-8")
    except UnicodeDecodeError as fehler:
        return f"keine gültige UTF-8-Folge ab Byte {fehler.start}"

    if "�" in text:
        return "Ersatzzeichen im Text: der Verlust liegt schon im Bestand"

    if any(spur in text for spur in SPUREN):
        # windows-1252 zurückrechnen: gelingt nur, wenn genau einmal fehldekodiert wurde
        original = text.encode("cp1252", errors="strict").decode("utf-8")
        return "einmal fehldekodiert, umkehrbar: " + original

    return "unauffällig"


print(einordnen("Grüße".encode("utf-8")))
print(einordnen("Grüße".encode("utf-8").decode("cp1252").encode("utf-8")))

Das Skript trennt die drei Fälle, die sich am Ergebnis unterscheiden lassen: eine Bytefolge, die gar kein gültiges UTF-8 ist, ein Text mit Ersatzzeichen und ein Text, dessen Rückweg über windows-1252 gelingt. Der letzte Zweig ist der nützliche, weil er den Beweis gleich mitliefert: Ergibt die Rückrechnung wieder lesbaren Text, war der Bestand in Ordnung und nur die Leseanweisung falsch. Schlägt die Rückrechnung fehl, enthält der Text Zeichen, die in windows-1252 nicht vorkommen, und die Ursache liegt woanders.

Ein Kodierungsfehler meldet sich nicht. Er wartet, bis jemand eine Bestellung mit einem Umlaut im Namen sucht und keine findet.

— XICTRAQ

Der Datenbestand ist der zweite Tatort

Ist die Anzeige richtig eingestellt und der Text bleibt kaputt, liegt der Fehler im Bestand. Dort hat er zwei übliche Ursachen: den Zeichensatz der Spalte und die Kodierung der Verbindung, über die die Anwendung liest und schreibt. Beide werden bei einer Migration gern übersehen, weil ein Export samt Import beide Seiten unbemerkt umdeuten kann. Dazu kommt eine Grenze, die in der Dokumentation steht und trotzdem regelmäßig überrascht: Der Zeichensatz utf8mb3 speichert ein bis drei Bytes je Zeichen und kennt keine ergänzenden Zeichen, während utf8mb4 dieselbe Kodierung mit vier Bytes für ergänzende Zeichen führt (MariaDB-Dokumentation). Zeichen außerhalb der Grundebene, etwa Symbole und seltene Schriftzeichen, passen deshalb in die eine Spalte und in die andere nicht.

  • Zeichensatz und Sortierregel je Tabelle und je Spalte prüfen, nicht nur die Vorgabe der Datenbank; einzelne Spalten tragen erfahrungsgemäß noch den Stand vor der letzten Umstellung.
  • Kodierung der Verbindung prüfen, mit der die Anwendung liest und schreibt; sie ist unabhängig vom Zeichensatz der Spalte und wird bei einem Wechsel der Laufzeitumgebung gern zurückgesetzt.
  • Kodierung der Vorlagen- und Übersetzungsdateien prüfen; eine einzelne Datei im alten Zeichensatz erzeugt einen Fehler, der nur auf wenigen Seiten auftritt und deshalb lange übersehen wird.
  • Sicherungen und Exporte gegenlesen: Eine Sicherung, die bereits fehldekodierten Text enthält, macht den Rückweg wertlos.
  • Ausgabewege getrennt prüfen — Seite, Schnittstelle, Rechnungsdokument, Ausfuhrdatei; jeder Weg trifft seine eigene Annahme.
  • Vor jeder Umkodierung eine Sicherung ziehen und die Dauer des Rückwegs messen, statt sie zu schätzen.
Eine Umkodierung ohne Rückweg ist ein Einwegschritt

Solange nur die Anzeige falsch ist, sind die Bytes vollständig und der Fehler ist umkehrbar. Sobald ein Umkodierungslauf über den Bestand gelaufen ist und dabei ungültige Folgen durch das Ersatzzeichen ersetzt wurden, ist die ursprüngliche Information in der Regel fort (Encoding Standard). Ziehen Sie deshalb vor jedem Lauf eine Sicherung, prüfen Sie sie auf Lesbarkeit, und lassen Sie den Lauf zuerst gegen eine Kopie laufen. Ein Lauf, der den ganzen Bestand in einer Minute umschreibt, braucht für den Rückweg dieselbe Sorgfalt wie für den Hinweg.

Formulare, Suche und Dateinamen: der stille Teil

Der sichtbare Zeichensalat ist der harmlosere Teil. Unangenehmer ist, was beim Absenden eines Formulars geschieht. Formulare senden ihre Werte in der Kodierung des Dokuments, und für den Fall, dass ein Zeichen in dieser Kodierung nicht darstellbar ist, kennt der Encoding Standard einen eigenen Fehlermodus. Der Standard hält dazu ausdrücklich fest, dass dieser Modus eine Folge erzeugt, die von echter Eingabe nicht zu unterscheiden ist und deshalb zu stillem Datenverlust führen kann (Encoding Standard). Praktisch heißt das: Ein Nachname mit Umlaut wird in eine Ziffernfolge verwandelt, die Anwendung speichert sie als Text, und niemand bemerkt es, bis jemand nach diesem Namen sucht.

Dieselbe Kette betrifft drei weitere Stellen, die selten mitgeprüft werden. Erstens die Suche: Ein Suchindex, der Text in einer Kodierung aufgenommen hat und Anfragen in einer anderen erhält, liefert null Treffer, ohne einen Fehler zu melden. Zweitens die Sortierung: Sortierregeln entscheiden, ob „Öl“ vor oder nach „Ozean“ steht, und eine Umstellung ändert die Reihenfolge von Listen, die jemand für stabil hält. Drittens Dateinamen, die in Kopffeldern übertragen werden; der Name eines heruntergeladenen Rechnungsdokuments ist ein häufiger Ort für Zeichensalat, weil er einen anderen Weg nimmt als der Seiteninhalt. Wenn eine Bestätigungsmail zu diesem Vorgang gehört, ist zusätzlich der Beitrag Double-Opt-in überwachen einschlägig, denn dort läuft dieselbe Kette über einen weiteren Zustellweg.

Ein Zeichen, das im Formular verloren geht, kommt nicht zurück

Prüfen Sie die Eingabestrecke einmal vollständig mit einem Testdatensatz, der Umlaute, ein Eszett, ein Euro-Zeichen und ein typografisches Anführungszeichen enthält: Formular absenden, Datensatz in der Datenbank ansehen, Bestätigungsmail lesen, Datensatz in der Verwaltungsansicht suchen. Vier Stationen, vier Gelegenheiten für einen stillen Verlust. Der Durchlauf dauert wenige Minuten und deckt erfahrungsgemäß mindestens eine Stelle auf, an der die Kette nicht durchgängig ist.

Der Ablauf vor und nach einem Umzug

Aus den vorangegangenen Abschnitten wird eine Reihenfolge. Sie setzt voraus, dass der Stand vor dem Umzug festgehalten wird, denn ohne Vergleichsstand ist nach dem Umschalten nicht mehr entscheidbar, ob ein Zeichen schon vorher falsch war.

  1. Vor dem Umzug, Bestandsaufnahme: Kodierung je Schicht notieren — Spalte, Verbindung, Vorlagendateien, Kopffeld, Dokumentangabe. Fünf Zeilen je Anwendung, schriftlich.
  2. Vor dem Umzug, Referenzstichprobe: Eine feste Liste von Adressen festhalten, die Umlaute, ein Eszett, ein Euro-Zeichen, typografische Anführungszeichen und mindestens ein Zeichen außerhalb der Grundebene enthalten. Diese Liste ist später der Maßstab.
  3. Im Übergang, Vorschau messen: Den neuen Stand zuerst unter einer Vorschauadresse prüfen und dort Kopffeld, erste 1024 Bytes und Datenbestand gegen die Referenzstichprobe halten.
  4. Nach dem Umschalten, Kopf und Dokument: Kopffeld und Dokumentangabe messen, bevor irgendetwas am Inhalt geändert wird. Diese Messung entscheidet, ob die Reparatur in die Konfiguration oder in den Bestand gehört.
  5. Nach dem Umschalten, Bestand: Textvergleich über alle Adressen laufen lassen und die Treffer nach Muster gruppieren; ein Bruch, der genau eine Vorlage betrifft, sieht anders aus als einer, der die halbe Datenbank betrifft.
  6. Nach dem Umschalten, Eingabewege: Formularstrecke, Suche, Sortierung und Dateinamen mit demselben Testdatensatz gegenprüfen.
  7. Dauerhaft: Textvergleich und die Prüfung der Kodierungsangabe im laufenden Betrieb behalten, nicht nach zwei Wochen abschalten.
Die eine Stichprobe, die den Umzug trägt

Wenn nur eine Sache aus diesem Ablauf umgesetzt wird, dann die Referenzstichprobe aus Schritt zwei. Sie kostet eine halbe Stunde, sie ist nach dem Umschalten in wenigen Minuten nachgefahren, und sie beantwortet die Frage, die sonst tagelang offenbleibt: War dieses Zeichen vorher richtig? Ohne Vergleichsstand endet diese Frage erfahrungsgemäß in einer Diskussion statt in einer Messung.

Kodierung gehört in die Dauerprüfung, nicht in die Umzugsliste

Ein Umzug ist der auffälligste Anlass, aber nicht der einzige. Dieselbe Kette bricht bei einem Wechsel der Laufzeitumgebung, bei einer Aktualisierung, die eine Vorlage ersetzt, bei einem neuen Ausgabeweg und bei einem Zwischenspeicher, der einen alten Stand weiterreicht; dazu der Beitrag veraltete Inhalte nach dem Deploy finden. Auch der Kalender spielt mit: Wer Auswertungen über einen Umstellungstag hinweg vergleicht, sieht Abweichungen, die keine sind, wie der Beitrag Zeitumstellung im Monitoring zeigt. Und wer Inhalte über Schnittstellen bezieht, bekommt die Kodierungsfrage samt Abkündigungsfristen von der Gegenseite mitgeliefert; wie sich das ankündigt, steht im Beitrag Sunset- und Deprecation-Header lesen.

Die Standards sind an dieser Stelle eindeutig, und das macht die Dauerprüfung einfach. Der Encoding Standard verlangt von Autoren, UTF-8 zu verwenden und es mit der Kennzeichnung „utf-8“ zu benennen (Encoding Standard). Der HTML Living Standard verlangt, dass die tatsächlich verwendete Kodierung eines Dokuments UTF-8 ist, unabhängig davon, ob eine Angabe vorhanden ist (HTML Living Standard), und er verlangt von Autorenwerkzeugen, für neu angelegte Dokumente UTF-8 als Vorgabe zu verwenden (HTML Living Standard). Eine Kodierungsangabe ist dabei auch dann erforderlich, wenn alle Zeichen im ASCII-Bereich liegen, weil sie für Formulareingaben und für skriptgenerierte Adressen gebraucht wird (HTML Living Standard). Wer diese vier Sätze als Prüfregeln formuliert, hat einen Test, der sich automatisieren lässt; wie technische Prüfungen dieser Art dauerhaft laufen, beschreibt der Beitrag technisches SEO automatisiert überwachen. Wie die Befunde in einer Ansicht zusammenlaufen, zeigt die Demo-Umgebung.

Quellen und Normen

Dieser Beitrag stützt sich auf den WHATWG Encoding Standard (Preface, Abschnitt 2 Security background, Abschnitt 4.1 Encoders and decoders, Abschnitt 4.2 Names and labels), den WHATWG HTML Living Standard (Abschnitt 4.2.5.4 zur Kodierungsangabe und Abschnitt 13.2.3 zur Bestimmung der Kodierung), RFC 3629 zu UTF-8, RFC 9110 Abschnitt 8.3 zu Content-Type sowie die Dokumentation der quelloffenen Datenbank MariaDB zu den Unicode-Zeichensätzen. Es handelt sich durchgängig um Normtexte und Herstellerdokumentation, nicht um Erhebungen: Sie sagen, was gelten soll, nicht wie häufig davon abgewichen wird. Jede Zahl ist im Beitrag mit ihrer Quelle ausgewiesen.

Woran erkenne ich, ob nur die Anzeige oder schon der Datenbestand betroffen ist?
Rufen Sie denselben Inhalt auf zwei Wegen ab: einmal als Seite im Browser und einmal als Rohabruf über die Kommandozeile. Sieht der Rohabruf richtig aus und die Seite falsch, liegt der Fehler in der Kodierungsangabe. Steht der Zeichensalat schon in den gelieferten Bytes, ist in der Regel der Bestand betroffen. Enthält der Text Ersatzzeichen, ist die ursprüngliche Information typischerweise fort und der Rückweg führt über eine Sicherung.
Reicht es, die Kodierungsangabe im Dokument zu ergänzen?
Nur dann, wenn kein widersprechendes charset im Kopffeld gesendet wird. Gibt die Transportschicht eine unterstützte Kodierung an, gilt diese (HTML Living Standard), und die Angabe im Dokument bleibt wirkungslos. Zusätzlich muss die Angabe vollständig innerhalb der ersten 1024 Bytes des Dokuments stehen (HTML Living Standard); rutscht sie durch einen langen Kommentar oder ein eingebettetes Skript darüber hinaus, wird sie nicht gefunden.
Warum sieht die Startseite richtig aus und die Produktseite nicht?
Weil beide ihren Text aus verschiedenen Quellen beziehen. Menü, Überschriften und Fußzeile stehen häufig in Vorlagendateien, die beim Umzug unverändert mitkopiert wurden; Produkttexte, Beschreibungen und Kundenangaben kommen aus der Datenbank und laufen über die Verbindung, deren Kodierung sich beim Wechsel geändert hat. Deshalb ist eine Stichprobe über die Startseite erfahrungsgemäß kein tragfähiger Nachweis.
Was bedeutet das Rautezeichen mit dem Fragezeichen mitten im Text?
Das ist U+FFFD, das Ersatzzeichen. Ein Dekodierer setzt es im Fehlermodus „replacement“ ein, wenn eine Bytefolge in der angenommenen Kodierung ungültig ist (Encoding Standard). Es ist kein Anzeigefehler, sondern ein Hinweis darauf, dass an dieser Stelle bereits Information fehlt. Aus mehreren verschiedenen ungültigen Folgen entsteht dasselbe Zeichen, weshalb sich der ursprüngliche Inhalt daraus in der Regel nicht zurückrechnen lässt.
In welcher Reihenfolge werden Datenbank und Anwendung umgestellt?
Erfahrungsgemäß zuerst die Sicherung, dann die Verbindung, dann die Spalten, dann die Anwendung, und jeder Schritt einzeln mit einer Messung dazwischen. Wer Verbindung und Spalten gleichzeitig ändert, kann hinterher nicht mehr unterscheiden, welcher Schritt den Zeichensalat erzeugt hat. Bei einem Wechsel von utf8mb3 auf utf8mb4 belegt ein ergänzendes Zeichen vier statt höchstens drei Bytes (MariaDB-Dokumentation); erfahrungsgemäß gehört deshalb vorher geprüft, ob Indexlängen und Feldgrenzen dafür ausgelegt sind.
Wie oft sollte die Kodierung geprüft werden?
Anlassbezogen bei jedem Umzug, jeder Aktualisierung, die Vorlagen ersetzt, und jedem neuen Ausgabeweg, darüber hinaus dauerhaft als Textvergleich über den Bestand. Ein täglicher oder wöchentlicher Vergleich reicht für die meisten Seiten aus, weil ein Kodierungsbruch typischerweise mit einer Veröffentlichung entsteht und nicht schleichend. Entscheidend ist weniger die Frequenz als die Abdeckung: Geprüft werden sollte der ganze Bestand, nicht die Startseite.

Passend in XICTRAQ

In 60 Sekunden starten

Lassen Sie XICTRAQ Ihre Website bewachen.

Dauerhaft kostenloser Plan verfügbar. Keine Kreditkarte, keine Installation, keine versteckten Kosten.