So funktioniert URL-Kodierung
Eine URL darf nur eine kleine Menge ASCII-Zeichen enthalten, und manche davon haben eine Aufgabe: / trennt den Pfad, ? beginnt die Query, & und = teilen sie in Parameter, # beginnt das Fragment. Jedes andere Zeichen oder eines davon als reine Daten wird als % und zwei Hexziffern für jedes seiner Bytes in UTF-8 geschrieben. Das heißt Percent-Encoding (RFC 3986).
Leerzeichen → %20 (oder + in Formulardaten) & → %26 / → %2F é → C3 A9 → %C3%A9 € → E2 82 AC → %E2%82%AC
Welche Zeichen zu kodieren sind, hängt davon ab, was Sie kodieren. Ein einzelner Wert wie ein Suchbegriff muss auch / ? & = # kodiert haben, sonst würde er die URL zerstören, in die er kommt: Das ist encodeURIComponent in JavaScript und urlencode in PHP. Eine ganze URL muss sie behalten, sonst ist sie kein Link mehr: Das ist encodeURI. HTML-Formulare senden Leerzeichen als + statt %20 (application/x-www-form-urlencoded), ein + in einem Query-String bedeutet daher meist ein Leerzeichen.
Das Dekodieren kehrt es um: Jedes %XX wird zu einem Byte, und die Bytes werden als UTF-8 gelesen. Das eigene decodeURIComponent des Browsers meldet nur „URI malformed“, wenn etwas nicht stimmt. Diese Seite benennt die Sequenz und zeigt darauf: ein % ohne zwei Hexziffern danach oder Bytes, die kein gültiges UTF-8 sind, was meist bedeutet, dass der Text als Latin-1 kodiert wurde.
Beispiel
Der Suchbegriff „vps hosting/€5“ als ein Wert wird zu vps%20hosting%2F%E2%82%AC5: Das Leerzeichen ist %20, der Schrägstrich %2F, und das Euro-Zeichen, in UTF-8 drei Bytes, wird zu %E2%82%AC. Mit „Leerzeichen als + schreiben“ für Formulardaten wird daraus vps+hosting%2F%E2%82%AC5. Das Dekodieren von r%C3%A9sum%C3%A9 ergibt résumé, und das Dekodieren von caf%E9 scheitert an %E9, weil das é in Latin-1 ist, nicht in UTF-8.
Fragen
Was ist URL-Kodierung?
URL-Kodierung oder Percent-Encoding schreibt Zeichen, die in einer URL nicht erlaubt sind oder dort eine besondere Bedeutung haben, als % gefolgt von zwei Hexziffern pro Byte. Ein Leerzeichen wird zu %20, & zu %26 und é zu %C3%A9. So kann jeder Text sicher in einem Link oder einem Query-String übertragen werden.
Was ist der Unterschied zwischen encodeURI und encodeURIComponent?
encodeURI ist für eine ganze Adresse: Es behält Zeichen mit einer Aufgabe in einer URL wie : / ? # & = bei, damit der Link weiter funktioniert. encodeURIComponent ist für ein einzelnes Teilstück innerhalb einer URL, etwa einen Query-Wert: Es kodiert diese Zeichen ebenfalls, sodass ein & im Wert keinen neuen Parameter beginnen kann. Im Zweifel kodieren Sie jeden Wert mit encodeURIComponent und fügen sie dann zusammen.
Soll ein Leerzeichen %20 oder + sein?
Beides ist an verschiedenen Stellen richtig. Im Pfad einer URL muss ein Leerzeichen %20 sein. In einem Query-String, den ein HTML-Formular sendet (application/x-www-form-urlencoded), wird ein Leerzeichen als + geschrieben und ein echtes Pluszeichen als %2B. Die meisten Server lesen in einem Query-String beides. Schalten Sie beim Dekodieren von Formulardaten „+ als Leerzeichen lesen“ ein.
Warum erhalte ich beim Dekodieren „URI malformed“?
Entweder folgen auf ein % nicht zwei Hexziffern, etwa bei einem schlichten „100%“ oder „%G1“, oder die %XX-Bytes sind kein gültiges UTF-8, oft weil der Text in Latin-1 kodiert wurde (é als %E9) oder ein Mehrbyte-Zeichen abgeschnitten wurde. Diese Seite zeigt, welche Sequenz falsch ist und wo sie steht, damit Sie sie korrigieren können.
Wie dekodiere ich eine URL auf der Kommandozeile oder im Code?
In JavaScript: decodeURIComponent(s), nach s.replace(/\+/g, ' ') bei Formulardaten. In Python: urllib.parse.unquote(s), oder unquote_plus(s) für Formulardaten. In PHP: rawurldecode($s), oder urldecode($s), das auch + in ein Leerzeichen umwandelt. In einer Shell mit installiertem Python: python3 -c "import sys, urllib.parse as u; print(u.unquote(sys.argv[1]))" 'r%C3%A9sum%C3%A9'.