Erklärte URL-Kodierung: Percent-Encoding, encodeURI vs. encodeURIComponent und der %2520-Fehler
Jeder Entwickler, der eine URL mit Benutzereingaben erstellt hat, ist auf Folgendes gestoßen: Ein Suchbegriff mit einem Leerzeichen oder einem kaufmännischen Und-Zeichen unterbricht den Link und plötzlich fehlt die Hälfte der Suchanfrage auf dem Server. Die Lösung ist die URL-Kodierung, auch Prozentkodierung genannt, aber sie enthält zwei Funktionen, die leicht zu verwechseln sind, und einen Fehler, der in Ihren Links den verwirrenden %2520-Wert erzeugt. Dieser Leitfaden klärt alles auf.
Warum URLs überhaupt eine Kodierung benötigen
URLs dürfen nur einen begrenzten Satz von Zeichen enthalten, der durch einen Standard namens RFC 3986 definiert ist. Dieser Satz besteht im Wesentlichen aus nicht reservierten Zeichen, Buchstaben, Ziffern und einigen Symbolen wie Bindestrich und Unterstrich sowie einer Handvoll reservierter Zeichen mit besonderer struktureller Bedeutung, z. B. ? um eine Abfrage zu starten, & um Parameter zu trennen, = um einen Schlüssel mit einem Wert zu koppeln, / für Pfadsegmente und # für ein Fragment. Alles außerhalb dieses Satzes, Leerzeichen, Buchstaben mit Akzent, Emojis oder ein reserviertes Symbol, das als Daten statt als Struktur verwendet wird, muss codiert werden, sonst wird die URL unterbrochen.
Bei der Prozentkodierung wird dazu ein unsicheres Zeichen durch ein Prozentzeichen gefolgt von seinem zweistelligen hexadezimalen Bytewert ersetzt. Ein Leerzeichen wird zu %20. Ein kaufmännisches Und wird zu %26. Ein At-Zeichen wird zu %40. Auf der anderen Seite dekodiert der Server diese wieder in die Originalzeichen. Das gesamte System ist so konzipiert, dass beliebiger Text innerhalb der starren Struktur einer URL angezeigt werden kann, ohne dass er als Teil dieser Struktur verwechselt wird.
Das Kernproblem: Daten vs. Struktur
Dies ist die Situation, die die meisten Fehler verursacht. Stellen Sie sich eine Suche nach dem wörtlichen Text „Katzen & Hunde“ vor. Wenn Sie das direkt als q=cats & dogs in eine Abfragezeichenfolge einfügen, wird das & als Parametertrennzeichen gelesen, der Server sieht einen Parameter q=cats und einen zweiten bedeutungslosen Parameter dogs, und Ihre Suche wird unterbrochen. Auch der Platz bereitet Probleme. Das kaufmännische Und muss zu %26 und das Leerzeichen zu %20 werden, damit der Server erkennt, dass sie Teil des Werts und nicht der URL-Struktur sind. Beim Kodieren sagt man: „Dieses Zeichen sind Daten, kein Trennzeichen.“
encodeURI vs. encodeURIComponent
JavaScript bietet Ihnen zwei Codierungsfunktionen, und die Wahl der falschen ist einer der häufigsten URL-Fehler. Der Unterschied besteht darin, was sie als „sicher“ betrachten und in Ruhe lassen.
encodeURIComponent codiert alles, was reserviert ist, einschließlich /? & = # und mehr. Es ist für die Kodierung eines einzelnen Werts gedacht, den Sie in eine URL, einen Abfrageparameterwert, einen Suchbegriff oder ein Weiterleitungsziel einfügen. Benutze es für die Stücke. Im Gegensatz dazu lässt encodeURI bewusst die URL-Strukturzeichen (/ ? & =) in Ruhe, da es dazu gedacht ist, eine gesamte, bereits zusammengesetzte URL zu kodieren und gleichzeitig ihre Funktionalität beizubehalten. Benutze es für die ganze Zeit, selten.
Als Faustregel gilt: Wenn Sie einen Wert kodieren, der innerhalb einer URL steht, verwenden Sie encodeURIComponent. Wenn Sie eine vollständige URL codieren und nur vereinzelte illegale Zeichen korrigieren möchten, ohne deren Struktur zu zerstören, verwenden Sie encodeURI. Im Zweifelsfall möchten Sie fast immer encodeURIComponent, da Sie fast immer einen Wert codieren.
Der %2520-Fehler: Doppelkodierung
Das verwirrt beim ersten Mal alle. Sie sehen %2520 in einer URL, wo Sie %20 erwartet haben, und der Link ist defekt. Folgendes ist passiert: Eine Zeichenfolge, die bereits codiert war, wurde ein zweites Mal codiert. Die erste Kodierung hat ein Leerzeichen in %20 umgewandelt. Die zweite Kodierung kodierte dann das Prozentzeichen selbst, % wird zu %25 und verwandelt %20 in %2520. Jetzt dekodiert der Server es einmal in %20 (wörtlich der Text „%20“) statt in ein Leerzeichen, und alles nachgeschaltete ist falsch.
Die Ursache liegt fast immer in der Codierung eines bereits codierten Werts, z. B. darin, eine URL aus einer bereits URL-codierten Zeichenfolge zu erstellen und diese dann erneut durch den Encoder laufen zu lassen. Die Regel, um dies zu vermeiden: Kodieren Sie immer nur rohen, unkodierten Text. Kodieren Sie niemals eine URL oder einen Wert, der bereits kodiert ist. Wenn Sie nicht sicher sind, ob eine Zeichenfolge bereits codiert ist, decodieren Sie sie zuerst und codieren Sie sie dann genau einmal.
Die Mehrdeutigkeit des Pluszeichens
Noch eine Falle. In einer Abfragezeichenfolge wird ein Pluszeichen (+) manchmal als Leerzeichen interpretiert, ein Erbe der älteren HTML-Formularkodierung application/x-www-form-urlencoded. Aber in einem URL-Pfad ist + ein wörtliches Plus. Diese Inkonsistenz bedeutet, dass ein + in Ihren Daten an einer Stelle als Leerzeichen und an einer anderen als Pluszeichen gelesen werden kann. Der sichere Weg besteht darin, ein Leerzeichen immer als %20 zu kodieren, was überall eindeutig ist, anstatt sich auf + zu verlassen. Wenn sich Leerzeichen in Pluszeichen verwandeln oder umgekehrt, ist meist diese Mehrdeutigkeit die Ursache.
Der praktische Imbiss
Kodieren Sie die Werte, die Sie in URLs eingeben, verwenden Sie encodeURIComponent für diese Werte, kodieren Sie nur Rohtext, um den Doppelkodierungsfehler %2520 zu vermeiden, und bevorzugen Sie %20 gegenüber + für Leerzeichen. Wenn Sie eine URL manuell erstellen oder überprüfen müssen, können Sie mit einem schnellen Encoder und Decoder genau sehen, was aus einer Zeichenfolge wird, und diese Probleme erkennen, bevor sie auftreten.