Dlaczego adresy URL trzeba kodować
Adres URL może zawierać tylko ograniczony zestaw znaków ASCII, a kilka z nich ma swoje zadanie. ? rozpoczyna ciąg zapytania, & oddziela parametry, = oddziela nazwę od wartości, # rozpoczyna fragment, a / oddziela segmenty ścieżki. Jeśli wyszukiwana fraza lub nazwa pliku zawiera któryś z tych znaków, przeglądarka lub serwer odczyta go jako element struktury, a nie jako dane.
Kodowanie procentowe rozwiązuje ten problem, zapisując kłopotliwy znak jako % i dwie cyfry szesnastkowe. Spacja staje się %20, & staje się %26, / staje się %2F. Znaki spoza ASCII są najpierw zamieniane na bajty UTF-8, a każdy bajt jest kodowany osobno, więc é staje się %C3%A9, a jedno emoji zamienia się w cztery grupy %XX.
Sytuacje, w których jest to potrzebne:
- Budowanie linku, w którym parametrem jest zapytanie wyszukiwania, adres przekierowania lub adres e-mail.
- Umieszczanie adresu URL wewnątrz innego adresu, np. wartości
returnTolubredirect_uriw procesie logowania. - Debugowanie webhooków i linków analitycznych, które przychodzą jako nieczytelna „zupa” z
%. - Czytanie logów serwera, w których żądane ścieżki zapisywane są w postaci zakodowanej.
Tryb komponentu a tryb pełnego URL
Pole wyboru Koduj cały URL (zachowaj :/?&=) decyduje o jednej z dwóch różnych reguł, a wybranie niewłaściwej to najczęstszy błąd.
Domyślnie: kodowanie komponentu
Gdy pole jest odznaczone, kodowane jest wszystko poza literami, cyframi i - _ . ! ~ * ' ( ). To właściwy wybór dla pojedynczej wartości, która trafi po = w ciągu zapytania lub do jednego segmentu ścieżki. Tekst rock & roll/live staje się rock%20%26%20roll%2Flive, który może bezpiecznie trafić do ?q= bez psucia listy parametrów.
Cały URL
Gdy pole jest zaznaczone, znaki nadające adresowi URL strukturę są zachowywane: : / ? # & = + , ; @ $ oraz te wymienione wyżej. Spacje, litery spoza ASCII i kilka innych znaków są nadal kodowane. Używaj tego trybu, gdy masz kompletny adres, który jest prawie poprawny, np. https://example.com/files/annual report.pdf, i trzeba poprawić tylko spację.
Tryb pełnego URL nie odróżni strukturalnego & od takiego, który należy do wartości. W https://shop.example/?q=salt & pepper znak & zostaje bez zmian, a serwer widzi uszkodzony parametr. W takim przypadku zakoduj samą wartość w trybie komponentu i wklej ją do adresu.
Spacje, plusy i podwójne kodowanie
Istnieją dwie konwencje zapisu spacji. Ścieżki i ogólne kodowanie URL używają %20; formularze HTML (application/x-www-form-urlencoded) używają +. Ten koder zawsze tworzy %20, które każdy serwer rozumie w obu miejscach.
Dekoder zamienia + na spację przed dekodowaniem, bo tak należy rozumieć ciągi zapytań zakodowane jak formularz. Efekt uboczny: dosłowny plus, który nigdy nie został zakodowany, np. C++ w ścieżce, zostanie zdekodowany jako spacje. Jeśli oryginalny tekst zawierał prawdziwy znak plus, powinien zostać wysłany jako %2B, a taka forma dekoduje się poprawnie.
Podwójne kodowanie to druga klasyczna pułapka. Sam znak % jest kodowany jako %25, więc ponowne przepuszczenie już zakodowanego ciągu przez koder zamienia %20 w %2520. Jeśli w niedziałającym linku widzisz %25, a po nim dwie cyfry szesnastkowe, zdekoduj go raz i sprawdź wynik.
Gdy dekodowanie się nie udaje
Komunikat „Nieprawidłowy zakodowany ciąg” pojawia się, gdy po % nie ma dwóch cyfr szesnastkowych albo gdy bajty nie tworzą poprawnego UTF-8. Typowe przyczyny:
- Ucięty link, przerwany w środku sekwencji
%C3%A9. - Dosłowny znak procentu, jak w
50% off, który nigdy nie został zakodowany. - Tekst zakodowany dawno temu w przestarzałej jednobajtowej stronie kodowej, takiej jak Windows-1251 czy Latin-1, gdzie
éto%E9zamiast%C3%A9.
W dwóch pierwszych przypadkach popraw uszkodzony fragment ręcznie. Dla przestarzałych stron kodowych nie ma niezawodnej automatycznej poprawki, bo ten sam bajt oznacza różne litery w różnych stronach kodowych.
Pokrewne kodowania
Kodowanie procentowe to nie to samo co Base64, które zamienia dowolne bajty w zwarty ciąg znaków, ani encje HTML, takie jak &, przeznaczone dla tekstu wewnątrz HTML. Do czytelnych adresów tworzonych z tytułów Generator slugów URL daje czystsze wyniki niż kodowanie: My Trip to Kraków staje się my-trip-to-krakow zamiast My%20Trip%20to%20Krak%C3%B3w.
Kodowanie i dekodowanie działają w przeglądarce, więc tokeny i prywatne parametry w adresie URL nigdzie nie są wysyłane.