URLs dürfen nur einen eingeschränkten Satz von ASCII-Zeichen enthalten. Alles andere — Leerzeichen, Akzente, Emoji und die Satzzeichen, die URLs strukturell verwenden — muss als Prozentzeichen gefolgt vom Bytewert in Hex geschrieben werden. Mehr ist Prozentkodierung nicht. Interessant wird es bei der Frage, welche Zeichen zu kodieren sind: Zu viele zu kodieren zerstört eine URL genauso gründlich wie zu wenige.
Es gibt zwei Encoder, und der falsche macht Dinge kaputt
JavaScript bietet encodeURI und encodeURIComponent, und sie unterscheiden sich um genau elf Zeichen: # $ & + , / : ; = ? @. encodeURI lässt sie in Ruhe; encodeURIComponent maskiert sie.
Diese Liste ist nicht willkürlich — es sind genau die Zeichen, die in einer URL strukturell etwas bedeuten. Der Schrägstrich trennt Pfadsegmente, das Fragezeichen beginnt die Query, das kaufmännische Und trennt Parameter, die Raute leitet das Fragment ein. Die Regel folgt also direkt: Nimm encodeURI, wenn du eine ganze URL hast und ihr Skelett unangetastet lassen willst. Nimm encodeURIComponent, wenn du einen einzelnen Wert hast, der gleich in eine URL eingesetzt wird — ein Query-Parameter, ein Pfadsegment.
Verwechselst du sie, scheitert es leise. Kodiere eine ganze URL mit encodeURIComponent, und du bekommst eine Zeichenkette, in der https%3A%2F%2F kein Schema mehr ist und die niemand abrufen wird. Kodiere einen Query-Wert mit encodeURI, und ein Wert mit & zerfällt stillschweigend in zwei Parameter — was nicht nur ein Fehler ist, sondern genau der Mechanismus von Query-Parameter-Injection. Dieses Tool maskiert den vollständigen Komponenten-Satz, die sichere Vorgabe für den häufigen Fall: einen Wert kodieren.
Das Pluszeichen ist kein Leerzeichen, außer wenn doch
Das ist die subtilste Falle des ganzen Themas, und sie ist echt mehrdeutig, nicht bloß verwirrend. In RFC 3986, der Spezifikation für URLs, ist ein Leerzeichen %20 und ein Plus ein wörtliches Plus. Aber HTML-Formulare nutzen nicht RFC 3986 — sie nutzen application/x-www-form-urlencoded, eine ältere Konvention, in der ein Leerzeichen als + geschrieben wird.
Dadurch dekodiert dieselbe Zeichenkette je nach Leser auf zwei verschiedene Arten. decodeURIComponent("a+b") liefert "a+b" und behält das Plus. new URLSearchParams("q=a+b").get("q") liefert "a b" und macht ein Leerzeichen daraus. Keines ist falsch; sie setzen verschiedene Spezifikationen um. Deshalb kommt eine Suche nach "C++" so oft als "C " an — irgendetwas in der Kette hat Formular-Regeln auf URL-Regeln angewandt.
Praktisch: Nimm innerhalb einer Query-Zeichenkette an, dass + Leerzeichen bedeutet, denn davon gehen Browser und praktisch jedes Server-Framework aus. Überall sonst in einer URL — Pfadsegment, Fragment — ist ein Plus ein Plus. Die RFC-1738-Checkbox auf dieser Seite schaltet die Ausgabe genau deswegen auf die Formular-Konvention um.
Warum das Dekodieren von "100%" einen Fehler wirft
Ein Prozentzeichen ist in einer kodierten URL kein gewöhnliches Zeichen — es ist ein Escape-Marker, und der Dekodierer verlangt danach exakt zwei Hex-Ziffern. Gib decodeURIComponent die Zeichenkette "100%", und es liefert nicht "100%"; es wirft URIError: URI malformed, weil nach dem Prozent nichts zu lesen ist.
Das taucht mit echten Daten ständig auf. Rabattcodes, Statistiken, alles mit einem wörtlichen Prozentzeichen bringt einen Dekodierer zu Fall, sofern das Prozent nicht selbst als %25 kodiert wurde. Siehst du URIError bei Benutzerdaten, liegt der Fehler fast immer stromaufwärts: Etwas hat die URL durch Zeichenkettenverkettung gebaut statt jeden Wert ordentlich zu kodieren.
Nicht-ASCII-Zeichen werden zu mehreren Bytes
Prozentkodierung arbeitet auf Bytes, nicht auf Zeichen, und moderne URLs transportieren UTF-8. Ein Zeichen außerhalb von ASCII wird also zu einem Escape pro Byte: é sind zwei Bytes und werden zu %C3%A9, ein Emoji sind vier Bytes und wird zu zwölf Escape-Zeichen.
Das lohnt sich zu merken, wenn eine Längenbegrenzung im Spiel ist. Ein Pfad oder Parameter, der auf Japanisch oder Arabisch bequem kurz aussieht, kann kodiert dreimal so lang sein, und manche Systeme setzen für die ganze URL noch Grenzen um die 2000 Zeichen.
Häufige Fragen
Wird meine URL an einen Server geschickt?
Nein. Dieses Tool ist als "client" gekennzeichnet: Die Kodierung läuft in deinem Browser-Tab, der Text verlässt das Gerät nie. Erwähnenswert, weil URLs aus echten Systemen oft Sitzungstokens, API-Schlüssel oder Kundenkennungen in der Query tragen — trifft das auf deine zu, behandle sie als Zugangsdaten, egal in welches Tool du sie einfügst.
Soll ich + oder %20 für ein Leerzeichen nehmen?
%20 funktioniert immer — es ist in jedem Teil einer URL gültig und jeder Dekodierer versteht es. + bedeutet nur innerhalb einer Query-Zeichenkette Leerzeichen, und nur nach Formular-Regeln. Im Zweifel nimm %20; das ist nie falsch. Nimm + nur, wenn du bewusst formularkodierte Daten erzeugst und weißt, dass der Leser sie erwartet.
Meine kodierte URL enthält %2520. Was ist passiert?
Doppelkodierung. %25 ist ein kodiertes Prozentzeichen, %2520 ist also das, was aus %20 wird, wenn es ein zweites Mal durch einen Encoder läuft — aus % wurde %25 und die 20 kam mit. Irgendetwas in deiner Kette kodiert einen bereits kodierten Wert. Kodiere genau einmal, an der Stelle, wo du die URL baust, und nie auf einer Zeichenkette, die du nicht selbst konstruiert hast.
Warum zerlegt mein kaufmännisches Und meinen Parameter in zwei?
Weil es beim Bauen des Parameterwerts nicht kodiert wurde. In einer Query-Zeichenkette ist & der Trenner zwischen Parametern, ein Wert mit rohem & ist also vom Beginn eines neuen nicht zu unterscheiden. Es muss %26 werden. Das ist zugleich der Mechanismus hinter Parameter-Injection, also lohnt es, es an der Stelle richtig zu beheben, wo du die URL baust, statt das Symptom zu flicken.
Muss ich eine URL aus der Adressleiste kodieren?
Mit ziemlicher Sicherheit nicht — sie ist bereits kodiert, und erneutes Kodieren erzeugt das %2520-Problem von oben. Browser zeigen eine dekodierte, lesbare Fassung und halten intern die kodierte. Was du siehst, ist nicht, was gesendet wird. Enthält eine URL bereits %-Escapes, wurde sie kodiert: Dekodiere sie zum Lesen, kodiere sie nicht noch einmal.