Hand aufs Herz — wer hatte noch keinen Bug, weil Leerzeichen oder Sonderzeichen in einer URL Probleme verursacht haben? Vielleicht hat ein & in einem Suchbegriff seltsames Verhalten ausgelöst. Oder Sie haben %20 in einer URL gesehen und sich gefragt, was das soll. Klären wir das ein für alle Mal.
Warum URLs kodiert werden müssen
URLs dürfen nur bestimmte Zeichen enthalten. Die RFC 3986 Spezifikation definiert „nicht reservierte" Zeichen, die immer sicher sind: A-Z, a-z, 0-9, -, _, . und ~. Alles andere — Leerzeichen, &, =, ?, Nicht-ASCII-Zeichen wie ñ oder 日本語 — muss prozentkodiert werden.
Wie Prozentkodierung funktioniert
Es ist recht einfach: Man nimmt den UTF-8-Bytewert des Zeichens und stellt jedes Byte als % gefolgt von zwei Hexadezimalziffern dar.
Beispiele:
- Leerzeichen →
%20 &→%26=→%3Dé→%C3%A9(zwei Bytes in UTF-8)日→%E6%97%A5(drei Bytes in UTF-8)
Also wird Hello World im URL-Pfad zu Hello%20World.
Der häufigste Fehler: Doppelte Kodierung
Das ist der häufigste URL-Kodierungsfehler, den ich sehe — und er ist tückisch. Sie kodieren einen String, übergeben ihn an eine Funktion, die ihn nochmal kodiert. Jetzt wird %20 (ein bereits kodiertes Leerzeichen) zu %2520, weil das %-Zeichen selbst kodiert wird.
Beispiel für das Problem:
Die Lösung: Werte nur einmal kodieren, auf der richtigen Ebene. Kodieren Sie nichts, was bereits kodiert ist.
Plus-Zeichen vs. %20 — Ja, es ist verwirrend
In Query-Strings können Leerzeichen als + oder %20 dargestellt werden. Die +-Konvention stammt aus der HTML-Formularkodierung (application/x-www-form-urlencoded). Im URL-Pfad ist nur %20 gültig.
Also https://example.com/hello world → Pfad wird kodiert zu https://example.com/hello%20world
Aber https://example.com/search?q=hello world → Query kann ?q=hello+world oder ?q=hello%20world sein
encodeURI vs. encodeURIComponent
JavaScript bietet Ihnen zwei Funktionen, und die falsche zu verwenden ist ein klassischer Fehler:
encodeURI()— Kodiert eine vollständige URL. Lässt:,/,?,#,&,=unverändert, da sie strukturelle Teile der URL sind.encodeURIComponent()— Kodiert einen URL-Bestandteil (z.B. einen Query-Parameter-Wert). Kodiert AUCH:,/,?,#,&,=, da diese Teil der Daten sein könnten.
Faustregel: Verwenden Sie encodeURIComponent() für Werte, niemals für ganze URLs. Die MDN-Dokumentation erklärt den Unterschied hervorragend.
Andere Sprachen
- Python:
urllib.parse.quote()für Pfade,urllib.parse.urlencode()für Query-Strings — Dokumentation hier - Java:
URLEncoder.encode()(verwendet+für Leerzeichen — Vorsicht!) - PHP:
urlencode()für Query-Strings,rawurlencode()für Pfade
Schnelle Tipps
- Immer nur Parameter-Werte kodieren, nie ganze URLs
- Auf der Empfängerseite nur einmal dekodieren — kodierte Werte nicht durch mehrere Schichten durchreichen
- Testen Sie mit Grenzfällen: Leerzeichen,
&,=,#, Nicht-ASCII-Zeichen und Emoji
URLs sicher in JavaScript erstellen
Der richtige Weg, URLs mit Query-Parametern zu erstellen, ist die Verwendung der integrierten URL- und URLSearchParams-APIs. Sie übernehmen die gesamte Kodierung für Sie:
Beachten Sie, wie URLSearchParams + für Leerzeichen verwendet (HTML-Formularkodierungs-Konvention) und das & im Wert korrekt kodiert, damit es nicht mit dem & verwechselt wird, das Parameter trennt. Das ist viel sicherer als String-Verkettung.
Häufige URL-Kodierungsfallen
1. Die gesamte URL kodieren statt nur die Werte. Wenn Sie encodeURIComponent() auf eine vollständige URL anwenden, werden ://, /, ? und & kodiert — und die URL wird komplett unbrauchbar. Kodieren Sie nur einzelne Parameterwerte.
2. Hash-Fragmente vergessen zu kodieren. Das #-Zeichen in einer URL startet einen Fragment-Identifikator. Wenn Ihre Daten ein # enthalten und Sie es nicht kodieren, verschwindet alles danach aus Sicht des Servers. Der Server sieht Fragment-Identifikatoren nie — sie sind nur clientseitig.
3. Internationale Domainnamen (IDN) nicht berücksichtigen. Domainnamen mit Nicht-ASCII-Zeichen wie example.日本 benötigen eine spezielle Behandlung namens Punycode-Kodierung. Diese ist getrennt von der Prozentkodierung und gilt nur für den Hostnamen-Teil der URL.
4. Leerzeichen inkonsistent kodieren. Einige Teile Ihres Systems kodieren Leerzeichen als +, andere als %20. Das funktioniert beim Dekodieren normalerweise gut, kann aber Probleme beim URL-Vergleich und Caching verursachen. Entscheiden Sie sich für eine Konvention und bleiben Sie dabei.
Prozentkodierung-Kurzreferenz
| Zeichen | Kodiert | Warum es kodiert werden muss |
| Leerzeichen | %20 oder + | In URLs nicht erlaubt |
& | %26 | Trennt Query-Parameter |
= | %3D | Trennt Schlüssel von Wert |
? | %3F | Startet Query-String |
# | %23 | Startet Fragment-Identifikator |
% | %25 | Das Escape-Zeichen selbst |
/ | %2F | Pfadtrenner |
@ | %40 | Wird im Userinfo-Abschnitt verwendet |
URL-Kodierung in verschiedenen Kontexten
URL-Kodierung ist nicht nur für Browser-URLs. Sie begegnet Ihnen in diesen häufigen Situationen:
- API-Anfragen: Query-Parameter in REST-API-Aufrufen müssen korrekt kodiert werden, besonders wenn sie Benutzereingaben enthalten
- Weiterleitungs-URLs: Wenn Sie eine Rückgabe-URL als Parameter übergeben (wie
?redirect=https://...), muss die gesamte Weiterleitungs-URL als Wert kodiert werden - OAuth-Flows: OAuth-Callback-URLs und State-Parameter sind notorisch knifflig, weil sie mehrere Schichten von URL-Kodierung beinhalten
- Deep Links: Mobile Deep Links folgen den gleichen URL-Kodierungsregeln, aber einige Plattformen haben zusätzliche Anforderungen
URL-Kodierungsprobleme debuggen
Wenn etwas mit der URL-Kodierung schiefgeht, hier meine Debug-Checkliste:
1. Auf doppelte Kodierung prüfen — Suchen Sie nach %25 in der URL, was bedeutet, dass ein % doppelt kodiert wurde
2. Die rohe Anfrage prüfen — Verwenden Sie die DevTools-Netzwerk-Registerkarte Ihres Browsers, um genau zu sehen, welche URL gesendet wurde, bevor der Browser die dekodierte Version anzeigt
3. Kodiert vs. dekodiert vergleichen — Fügen Sie die problematische URL in einen Decoder ein, um zu sehen, was sie tatsächlich enthält
4. Serverseitige Dekodierung prüfen — Einige Frameworks dekodieren URL-Parameter automatisch, und wenn Sie das manuell obendrauf machen, gibt es Probleme
Die Anatomie einer URL
Okay, machen wir einen Schritt zurück. Bevor wir tiefer in die Kodierung einsteigen, müssen Sie wirklich verstehen, woraus eine URL besteht. Ich weiß, ich weiß — Sie verwenden URLs Ihre gesamte Karriere lang. Aber ich wette, Sie kennen nicht alle Teile mit ihren offiziellen Namen. Die meisten Entwickler nicht, und da beginnt die Verwirrung mit der Kodierung.
Laut RFC 3986 hat eine URL diese Struktur:
Lassen Sie mich die einzelnen Teile durchgehen:
- Scheme (
https,ftp,mailto) — Das Protokoll. Hier ist keine Kodierung nötig, es sind immer ASCII-Buchstaben. - Authority — Dies umfasst das optionale
user:password@(was Sie 2026 praktisch nie verwenden sollten), den Host (Domainname oder IP) und eine optionale Port-Nummer. - Path (
/search/results) — Der hierarchische Teil. Schrägstriche/trennen Segmente. Innerhalb jedes Segments müssen Sie Sonderzeichen kodieren, aber Sie kodieren NICHT die Schrägstriche selbst. - Query (
?q=hello&lang=en) — Schlüssel-Wert-Paare nach dem?. Das&trennt Paare,=trennt Schlüssel von Werten. Sie kodieren die Schlüssel und Werte, aber nicht die strukturellen&und=. - Fragment (
#section-2) — Der Teil nach#. Dieser ist interessant — er wird nie an den Server gesendet. Er ist rein clientseitig. Aber Sie müssen trotzdem Sonderzeichen darin kodieren.
Hier ist das, was Leute durcheinanderbringt: Verschiedene Teile der URL haben verschiedene Kodierungsregeln. Ein / ist im Pfad völlig in Ordnung (es ist ein Trennzeichen!), muss aber als %2F kodiert werden, wenn es innerhalb eines Query-Parameter-Werts vorkommt. Ein @-Zeichen ist im Authority-Abschnitt in Ordnung, sollte aber im Pfad kodiert werden. Deshalb verursachen Einheits-Kodierungsfunktionen so viele Bugs.
Stellen Sie es sich so vor: Die URL ist ein Satz mit Grammatikregeln. Die Sonderzeichen sind Satzzeichen. Sie würden kein Komma kodieren, das tatsächlich als Komma verwendet wird — Sie kodieren nur ein Komma, das Teil der Daten ist und mit Satzzeichen verwechselt werden könnte.
encodeURI vs. encodeURIComponent: Das JavaScript-Minenfeld
Also gut, dieses Thema macht mich absolut wahnsinnig, weil ich sehe, wie Entwickler es STÄNDIG falsch machen. JavaScript gibt Ihnen zwei Kodierungsfunktionen, und sie klingen fast identisch, aber die falsche zu verwenden wird Ihren Tag ruinieren.
Lassen Sie mich das klar darlegen:
encodeURI() ist dafür gedacht, eine vollständige URL zu kodieren. Es kodiert unsichere Zeichen, lässt aber die strukturellen in Ruhe — Dinge wie :, /, ?, #, &, =, @. Denn wenn Sie eine vollständige URL kodieren, wollen Sie offensichtlich nicht die URL-Struktur zerstören.
encodeURIComponent() ist dafür gedacht, einen einzelnen Wert zu kodieren, der in eine URL eingefügt wird. Es kodiert ALLES außer Buchstaben, Ziffern und - _ . ~. Das schließt :, /, ?, #, &, = ein — denn wenn diese in einem Wert vorkommen, sind sie Daten, keine Struktur.
Hier ein Vergleich, der es kristallklar macht:
| Zeichen | encodeURI() | encodeURIComponent() |
: | : (unverändert) | %3A |
/ | / (unverändert) | %2F |
? | ? (unverändert) | %3F |
# | # (unverändert) | %23 |
& | & (unverändert) | %26 |
= | = (unverändert) | %3D |
@ | @ (unverändert) | %40 |
| Leerzeichen | %20 | %20 |
é | %C3%A9 | %C3%A9 |
Jetzt wird es beängstigend. Schauen Sie, was passiert, wenn Sie die falsche Funktion verwenden:
Und der umgekehrte Fehler ist genauso schlimm:
Die goldene Regel: encodeURIComponent für Werte, encodeURI für vollständige URLs. Oder noch besser, verwenden Sie einfach die URL-API und lassen Sie den Browser das erledigen. Im Ernst, die URL- und URLSearchParams-Klassen existieren aus gutem Grund. Schauen Sie in die MDN encodeURIComponent-Docs und MDN encodeURI-Docs für alle Details.
URL-Kodierung in verschiedenen Sprachen
JavaScript ist nicht die einzige Sprache mit verwirrenden URL-Kodierungsfunktionen. Jede Sprache hat ihre eigenen Eigenheiten, und ich schwöre, einige sind sogar verwirrender als JavaScripts Paar.
Python — Eigentlich ziemlich vernünftig, wenn man das richtige Modul gefunden hat:
Java — Hier wird es seltsam. URLEncoder wurde für HTML-Formularkodierung entwickelt, nicht für allgemeine URL-Kodierung. Daher werden Leerzeichen zu + statt %20:
C# — .NET gibt Ihnen tatsächlich die richtigen Werkzeuge, aber es gibt ungefähr fünf verschiedene Methoden, die alle leicht unterschiedliche Dinge tun:
PHP — Oh PHP. Natürlich haben Sie zwei Funktionen mit fast identischen Namen, die leicht unterschiedliche Dinge tun:
Go — Sauber und vernünftig, wie Go es sein will:
Die Erkenntnis? Jede Sprache handhabt das + vs. %20 Thema anders, und jede Sprache hat mindestens eine Funktion, die Sie überraschen wird. Prüfen Sie immer die Dokumentation der Sprache, mit der Sie arbeiten. Gehen Sie nicht davon aus, dass es genauso funktioniert wie in JavaScript.
Unicode in URLs: Der Wilde Westen
Okay, hier wird es WIRKLICH interessant. Was passiert, wenn Sie Nicht-ASCII-Zeichen in eine URL setzen? Zum Beispiel, was wenn Sie eine URL mit Japanisch, Arabisch oder — ich scherze nicht — Emoji möchten?
Die Antwort involviert zwei komplett verschiedene Systeme, und sie zu verwechseln ist ein klassischer Fehler.
Für den Pfad- und Query-Teil: Sie verwenden Prozentkodierung. Nehmen Sie die UTF-8-Bytes des Zeichens und kodieren Sie jedes. Also wird café zu caf%C3%A9. Ihr Browser macht das automatisch und zeigt Ihnen normalerweise die hübsche Version in der Adressleiste, aber unter der Haube sendet er die prozentkodierte Version.
Für Domainnamen: Prozentkodierung wird NICHT verwendet. Stattdessen gibt es dieses wilde System namens Punycode. Es konvertiert Unicode-Domainnamen in ASCII-kompatible Strings, die mit xn-- beginnen.
Schauen Sie sich das an:
café.com→xn--caf-dma.commünchen.de→xn--mnchen-3ya.de例え.jp→xn--r8jz45g.jp
Warum zwei verschiedene Systeme? Weil DNS (das System, das Domainnamen in IP-Adressen umwandelt) in den 1980ern gebaut wurde und nur ASCII unterstützt. Also mussten sie einen Weg erfinden, Unicode in ASCII-Strings zu packen — und Punycode ist diese Erfindung. Die Pfad- und Query-Teile einer URL hingegen werden von Webservern verarbeitet, die mit prozentkodierte Bytes umgehen können.
Es gibt tatsächlich eine ganze Spezifikation für Unicode in URLs namens IRI (Internationalized Resource Identifiers), definiert in RFC 3987. Ein IRI ist im Grunde eine URL, die Unicode-Zeichen direkt erlaubt. Browser konvertieren IRIs hinter den Kulissen in URIs.
Und ja, Emoji-Domains existieren. 💩.la ist eine echte Domain (oder war es irgendwann). Sie wird mit Punycode zu xn--ls8h.la kodiert. Ich empfehle nicht, Emoji-Domains für etwas Ernstes zu verwenden, aber es ist ein lustiger Beweis, dass das System funktioniert.
Ein Stolperstein bei Unicode in URLs: verschiedene Unicode-Darstellungen des „gleichen" Zeichens. Zum Beispiel kann é als ein einzelner Codepunkt (U+00E9) oder als e + ein kombinierendes Akzentzeichen (U+0065 + U+0301) dargestellt werden. Diese erzeugen unterschiedliche prozentkodierte Strings! Der WHATWG URL Standard empfiehlt NFC-Normalisierung, aber nicht alle Systeme befolgen dies konsistent.
Doppelte Kodierung: Der Bug, der Ihre Träume verfolgt
Ich habe doppelte Kodierung bereits erwähnt, aber es verdient einen eigenen tiefen Einblick, weil dieser Bug wahrscheinlich mehr kollektive Entwicklerstunden verschwendet hat als jedes andere URL-bezogene Problem. War dort, habe das gemacht — mehrmals.
Hier das grundlegende Szenario:
Was ist passiert? Wenn Sie hello%20world ein zweites Mal kodieren, wird das %-Zeichen zu %25 kodiert. Also wird %20 zu %2520. Der Server sieht den buchstäblichen String %20 statt eines Leerzeichens.
Das klingt offensichtlich, wenn ich es so aufschreibe, aber in echten Codebasen ist es unglaublich heimtückisch. Hier sind die Szenarien, in denen doppelte Kodierung zuschlägt:
Proxy-Ketten. Sie senden eine Anfrage an Server A, der sie an Server B weiterleitet. Wenn beide Server die URL kodieren, bumm — doppelt kodiert. API-Gateways wie Kong, AWS API Gateway oder nginx Reverse Proxies sind häufige Übeltäter.
Weiterleitungsketten. Benutzer geht zu Seite A, wird zu Seite B weitergeleitet mit einem ?returnUrl=...-Parameter, und Seite B leitet erneut weiter mit der Rückgabe-URL als Parameter. Jede Weiterleitung könnte die URL erneut kodieren. Nach drei Weiterleitungen ist Ihre URL dreifach kodiert und komplett vermurkst.
Framework-"Helfer". Einige Web-Frameworks kodieren URL-Parameter automatisch. Wenn Sie vor der Übergabe an das Framework manuell kodieren, bekommen Sie doppelte Kodierung. Ich habe das bei Spring Boot, Express.js-Middleware und Djangos URL-Reversing gesehen.
Wie erkennt man doppelte Kodierung? Suchen Sie nach %25 in der URL. Das ist ein Prozentzeichen, das kodiert wurde, was normalerweise bedeutet, dass etwas doppelt kodiert wurde. Wenn Sie %2520 sehen, ist das ein doppelt kodiertes Leerzeichen. Wenn Sie %253D sehen, ist das ein doppelt kodiertes =-Zeichen.
So beheben Sie es:
Die beste Verteidigung ist, klare Grenzen in Ihrem Code zu etablieren: kodieren Sie an den Rändern (direkt bevor Sie eine HTTP-Anfrage senden oder direkt bevor Sie eine URL zur Anzeige erstellen), und übergeben Sie intern überall rohe, unkodierte Strings.
URL-Längenbeschränkungen und was man dagegen tun kann
Hier ist etwas, das Sie überraschen wird: Die HTTP-Spezifikation selbst definiert KEINE maximale URL-Länge. RFC 3986 sagt, URLs sollten „unbegrenzt lang" sein. Aber die reale Welt sieht das anders.
Verschiedene Komponenten in der Kette haben ihre eigenen Grenzen, und die kürzeste gewinnt:
| Komponente | Maximale URL-Länge |
| Internet Explorer (RIP) | 2.083 Zeichen |
| Chrome, Firefox, Safari | ~65.000+ Zeichen |
| Apache (Standard) | 8.190 Zeichen |
| Nginx (Standard) | 8.192 Zeichen |
| IIS (Standard) | 16.384 Zeichen |
| AWS ALB | 8.192 Zeichen |
| Cloudflare | 32.768 Zeichen |
Das alte 2.083-Zeichen-Limit vom IE hat früher alles bestimmt. Obwohl der IE jetzt im Grunde tot ist, behandeln einige Entwickler und Tools es immer noch als Evangelium. Aber in der Praxis können die meisten modernen Stacks viel längere URLs verarbeiten.
Trotzdem, nur weil Sie eine 65.000 Zeichen lange URL MACHEN können, heißt das nicht, dass Sie es SOLLTEN. Hier sind einige echte Gründe, URLs kurz zu halten:
- Server-Logs. Viele Logging-Systeme kürzen lange URLs, was das Debugging zum Albtraum macht.
- Kopieren & Einfügen. Benutzer kopieren und teilen URLs. Super-lange URLs brechen in E-Mails, Chat-Nachrichten und Dokumenten.
- SEO. Suchmaschinen empfehlen generell, URLs unter 2.000 Zeichen zu halten.
- Caching. Einige CDN- und Proxy-Cache-Schlüssel-Limits basieren auf URLs. Längere URLs = mehr Cache-Misses.
Was also tun, wenn Ihre URL zu lang wird? Freut mich, dass Sie fragen:
1. POST statt GET verwenden. Wenn Sie viele Daten senden, legen Sie sie in den Request-Body. Der Request-Body hat kein praktisches Größenlimit. Das ist die häufigste Lösung für komplexe Suchformulare mit vielen Filtern.
2. URL-Shortener oder Referenz-IDs verwenden. Generieren Sie ein kurzes Token, das auf den vollständigen Parametersatz verweist, der serverseitig gespeichert wird. Statt /search?filter1=abc&filter2=def&filter3=... bekommen Sie /search/saved/abc123.
3. Parameter komprimieren. Einige Apps base64-kodieren einen komprimierten JSON-Blob und setzen ihn in die URL. Nicht hübsch, aber es funktioniert. Sie sehen das bei Tools wie Grafana-Dashboard-URLs.
Formularkodierung: application/x-www-form-urlencoded
Reden wir über den Elefanten im Raum, der URL-Kodierung noch verwirrender macht: HTML-Formularkodierung. Wenn Sie ein HTML-Formular mit method="POST" absenden, kodiert der Browser die Formulardaten in einem Format namens application/x-www-form-urlencoded. Und dieses Format ist FAST dasselbe wie Standard-Prozentkodierung, aber mit einem entscheidenden Unterschied, der alle verrückt macht.
Leerzeichen werden zu + statt %20.
Das ist es. Das ist der Hauptunterschied. Aber oh je, sorgt das für Verwirrung.
Warum gibt es diesen Unterschied? Historische Gründe, natürlich. Die HTML-Formularkodierungs-Spezifikation ist älter als die URL-Kodierungs-Spezifikation, und sie verwendete + für Leerzeichen, weil... naja, jemand dachte in den 90ern, das sähe besser aus. Und jetzt sitzen wir für immer damit fest.
Wenn Sie ein HTML-Formular absenden, sendet der Browser einen Content-Type: application/x-www-form-urlencoded-Header, und der Server weiß, dass + als Leerzeichen zu interpretieren ist. Aber wenn Sie URLs manuell in JavaScript erstellen und + für Leerzeichen im Pfadteil verwenden, sieht der Server buchstäbliche Pluszeichen. Spaßige Zeiten.
Hier ist es in der Praxis wichtig:
Und dann gibt es multipart/form-data, was ein komplett anderes Biest ist. Wenn Ihr Formular Datei-Uploads enthält (), wechselt der Browser zu multipart/form-data-Kodierung, die Boundaries verwendet, um Felder zu trennen, statt &-Zeichen. Es verwendet überhaupt keine URL-Kodierung — jeder Teil hat seine eigenen Header und Body. Wenn Sie jemals versucht haben, eine Multipart-Anfrage manuell zu parsen, kennen Sie den Schmerz.
Der praktische Rat: Verwenden Sie URLSearchParams für Query-Strings und Formulardaten. Verwenden Sie FormData für Datei-Uploads. Versuchen Sie nicht, diese Dinge von Hand zu kodieren, es sei denn, Sie müssen es wirklich, wirklich tun.
Probieren Sie es selbst aus
Arbeiten Sie mit URLs, die falsch aussehen? Fügen Sie sie in unseren URL-Decoder ein, um die tatsächlichen Zeichen zu sehen. Müssen Sie einen Wert kodieren, bevor Sie ihn in eine URL einfügen? Der URL-Encoder erledigt das sofort. Und um komplexe URLs in ihre Bestandteile zu zerlegen, verwenden Sie den URL-Parser, um jeden Teil deutlich zu sehen.