URL-Kodierung — fachlich Prozentkodierung — ist der Mechanismus, mit dem das Web Sonderzeichen sicher in URLs transportiert. Jedes Mal, wenn ein Nutzer einen Suchbegriff mit Leerzeichen eingibt, jedes Mal, wenn eine API einen Query-String mit Ampersand empfängt, jedes Mal, wenn eine Weiterleitung einen Nicht-ASCII-Dateinamen erhält, steckt Prozentkodierung dahinter. Dieser Leitfaden zeigt die Regeln, die beiden JavaScript-APIs und die Fehler, die einem das Leben schwer machen.
Reserviert vs. unreserviert
RFC 3986 teilt URL-Zeichen in zwei Gruppen. Unreservierte Zeichen — A–Z, a–z, 0–9 und - _ . ~ — sind immer sicher. Reservierte Zeichen — : / ? # [ ] @ ! $ & ' ( ) * + , ; = — haben strukturelle Bedeutung (Schema vs. Pfad, Schlüssel vs. Wert, Komponente vs. Komponente) und müssen kodiert werden, wenn sie als Daten statt als Struktur auftauchen. Alles andere (Leerzeichen, Unicode, Binärbytes) muss stets kodiert werden.
Die Regel
Jedes zu entschärfende Byte wird zu einem Prozentzeichen gefolgt von zwei Hex-Ziffern. Ein Leerzeichen ist %20, ein Ampersand ist %26, ein Geviertstrich sind drei UTF-8-Bytes und damit drei Sequenzen: %E2%80%94. Decoder kehren das byteweise um.
encodeURI vs encodeURIComponent
JavaScript liefert zwei eingebaute Funktionen, die jedem mindestens einmal ein Bein stellen. encodeURI(str) nimmt an, str sei eine vollständige URL und lässt reservierte Zeichen in Ruhe (Schrägstriche, Doppelpunkte, Fragezeichen überleben). encodeURIComponent(str) nimmt an, str sei eine einzelne Komponente — ein Pfadsegment oder Wert — und entschärft alle reservierten Zeichen aggressiv. Praxisregel: Beim Zusammenbauen eines Query-Werts für ?key=value immer encodeURIComponent. Bei einer vollständigen URL, bei der nur Nicht-URL-Teile entschärft werden sollen, encodeURI.
Typische Fehler
- Doppelte Kodierung — bereits kodierten Text noch einmal kodieren.
%20wird zu%2520, der Decoder sieht ein wörtliches%20, und die URL enthält kein Leerzeichen mehr. - Falsche Funktion am falschen Teil —
encodeURIComponentauf eine ganze URL zerstört den Schema-Trenner. - Leerzeichen in Formulardaten vergessen — HTML-Formular-POSTs mit
application/x-www-form-urlencodedkodieren Leerzeichen als+, nicht als%20. Sonst überall%20. - Kein-UTF-8-Annahmen — moderne URL-Kodierung ist immer zuerst UTF-8, danach Prozentkodierung. Alte Systeme mit Latin-1 oder Shift_JIS sehen ähnlich aus, produzieren bei Nicht-ASCII aber Müll.
Wann welche verwenden
encodeURIComponent immer dann, wenn man einen Query-Wert dynamisch zusammensetzt. encodeURI, wenn man eine vom Nutzer gelieferte URL (eventuell mit Unicode im Pfad) sicher machen will, ohne ihre Struktur zu zerstören. Dekodieren mit decodeURIComponent, außer man will reservierte Zeichen bewusst erhalten — dann hätte man sie vermutlich gar nicht erst kodieren sollen.
