Warum in Adressen %20 und %C3%BC stehen

Eine URL darf nur eine kleine Zeichenmenge enthalten: Buchstaben, Ziffern und wenige Symbole. Alles andere, Leerzeichen, Umlaute, Emoji, wird zuerst in UTF-8-Bytes umgewandelt und dann jedes Byte als % mit zwei Hexadezimalziffern geschrieben. Das Leerzeichen wird zu %20, ü zu %C3%BC.

Manche Zeichen tragen Struktur: / trennt Pfadabschnitte, ? leitet den Query-String ein, & trennt Parameter, = trennt Name und Wert, # leitet das Fragment ein. Stehen sie in einem Wert, müssen sie kodiert werden, sonst zerbricht die Adresse. Das ist der Unterschied zwischen encodeURIComponent, das sie kodiert, und encodeURI, das sie stehen lässt, weil es auf einer ganzen URL arbeitet.

In Webformularen und Query-Strings wird das Leerzeichen oft auch als + geschrieben. Deshalb wandelt die Dekodierung hier + in ein Leerzeichen um, wie es Server tun; in einem Pfad bleibt + dagegen ein Plus.

Häufige Fehler

  • encodeURI für einen Parameterwert verwenden: Ein & im Wert teilt den Parameter in zwei.
  • Doppelt kodieren: Aus %20 wird %2520, und der Server erhält den wörtlichen Text %20.
  • Eine URL aus unkodierten Zeichenketten zusammensetzen: Neben Fehlern öffnet das die Tür für Parameter-Injektion.

Häufige Fragen

Was ist der Unterschied zwischen encodeURI und encodeURIComponent?

encodeURIComponent kodiert alles außer Buchstaben, Ziffern und - _ . ! ~ * ' ( ): Es ist für einen einzelnen Wert. encodeURI lässt zusätzlich : / ? # [ ] @ & = + $ , ; stehen: Es ist für eine bereits zusammengesetzte Adresse.

Warum ist ein Leerzeichen mal %20 und mal +?

%20 ist die allgemeine Kodierung eines Leerzeichens in einer URL. Das + stammt aus HTML-Formularen (application/x-www-form-urlencoded) und bedeutet nur im Query-String ein Leerzeichen.

Was ist Punycode?

So werden Domains mit Nicht-ASCII-Zeichen wie münchen.de im DNS geschrieben: xn--mnchen-3ya.de. Der Browser zeigt die lesbare Form, verwendet darunter aber die kodierte.

So funktioniert diese Berechnung

Kodierung: Der Text wird in UTF-8-Bytes umgewandelt, und jedes Byte außerhalb der erlaubten Menge wird zu %HH, wobei HH sein Hexadezimalwert ist. encodeURIComponent erlaubt nur A–Z a–z 0–9 - _ . ! ~ * ' ( ); encodeURI erlaubt zusätzlich ; , / ? : @ & = + $ #. Dekodierung: Jedes %HH wird wieder zu seinem Byte, die Bytes werden als UTF-8 gelesen und + wird zum Leerzeichen.