Chyby v kódování URL, které vývojáři stále dělají (a opravují)

Chyby v kódování URL jsou nenápadné, trvalé a často se objevují ve výrobě. A špatně umístěný %20, dvojitě zakódovaný ampersand nebo zmatený + vs prostor může přerušit volání API, poškodit data sledování a vytvořit zranitelnosti zabezpečení. Pojďme opravit ty nejčastější.
Otestujte své kódování s naším URL kodér/dekodér nástroj — vložte libovolný řetězec a okamžitě uvidíte zakódovaný výsledek.
encodeURI vs encodeURIComponent
JavaScript má dvě vestavěné funkce kódování a použití nesprávné je zdrojem chyb č. 1:
| Funkce | Kóduje | Zachovává | Použijte pro |
|---|---|---|---|
encodeURI | Prostory bez ASCII | : / ? # [ ] @ ! $ & ' ( ) * + , ; = | Kódování úplné adresy URL |
encodeURIComponent | Vše nad +: / ? # @ ! $ & ' ( ) * + , ; = | Pouze - _ . ~ a alfanumerické | Kódování hodnoty parametru dotazu |
// ŠPATNĚ — encodeURI zachovává & v hodnotách dotazu
const url = 'https://api.example.com/search?q=' + encodeURI('tom & jerry');
// Výsledek: https://api.example.com/search?q=tom%20&%20jerry
// & je zachováno — nyní to vypadá jako samostatný parametr! // SPRÁVNĚ
const url = 'https://api.example.com/search?q=' + encodeURIComponent('tom & jerry');
// Výsledek: https://api.example.com/search?q=tom%20%26%20jerry
Základní pravidlo: Použití encodeURIComponent pro jednotlivé hodnoty. Použití encodeURI pouze v případě, že máte úplnou adresu URL, která potřebuje pouze zakódované znaky jiné než ASCII.
Chyby dvojitého kódování
Ke dvojitému kódování dochází, když je již zakódovaný řetězec znovu zakódován:
const name = 'ahoj světe';
const encoded = encodeURIComponent(name); // ahoj%20world
const doubled = encodeURIComponent(encoded); // ahoj%2520světe
// %25 je kódování samotného %!
K tomu obvykle dochází, když:
- Rámec automaticky zakóduje parametry dotazu a vy je také předem zakódujete
- Adresa URL je zakódována před uložením a poté znovu zakódována při načtení
- Middleware zpracovává URL ve více vrstvách, přičemž každá přidává kódování
Detekce
Hledat %25 v URL — je to téměř vždy známka dvojitého kódování. Posloupnost %2520(dvojitě zakódovaný prostor) je klasická výmluva.
Zmatek + vs %20
V odeslání formuláře HTML (application/x-www-form-urlencoded), mezery se stanou +. Ve standardním kódování procent (RFC 3986) se stávají mezery %20.
To je důležité, protože:
decodeURIComponentdělá ne dekódovat+zpět do vesmíru – opouští to jako doslov+- Backendové rámce mohou nebo nemusí automaticky dekódovat
+v závislosti na parseru - Pokud vaše API očekává
%20ale přijímá+, hledá „červené+auto“ vrátí výsledky pro „červené+auto“ (s doslovným plusem) místo „červené auto“
// Bezpečné dekódování, které zpracovává + i %20
function safeDecodeParam(value) { return decodeURIComponent(value.replace(/\+/g, '%20'));
} Okrajová pouzdra UTF-8
Ne-ASCII znaky jako é, ü, 日本語 a emotikony musí být zakódovány v procentech jako jejich sekvence bajtů UTF-8:
encodeURIComponent('café') // caf%C3%A9
encodeURIComponent('日本語') // %E6%97%A5%E6%9C%AC%E8%AA%9E
encodeURIComponent('🔒') // %F0%9F%94%92
Problémy nastávají, když:
- Server očekává Latin-1, ale přijímá UTF-8 (mojibake — zkomolené znaky)
- Sloupce databáze nejsou nastaveny na UTF-8 a tiše se ořezávají vícebajtové znaky
- Soubory protokolu interpretují zakódované řetězce s nesprávnou znakovou sadou
Úskalí URL přesměrování a zpětného volání
Zpětná volání a adresy URL přesměrování OAuth jsou obzvláště náchylné k chybám v kódování:
// Vytvoření přesměrování OAuth
const redirectUri = 'https://myapp.com/callback?source=oauth';
const authUrl = `https://provider.com/auth?redirect_uri=${encodeURIComponent(redirectUri)}`;
// Správně: celá URL zpětného volání (včetně vlastního ?) je zakódována jako hodnota jediného parametru
Časté chyby:
- Nekódování
redirect_urivůbec — ten?ve zpětném volání rozdělí nadřazenou adresu URL - Kódování
redirect_uričástečně – kódování cesty, ale nikoli dotazu - Kódování celé adresy URL pro ověření namísto pouze hodnoty parametru
Tyto chyby často vytvářejí zranitelnosti otevřeného přesměrování, které útočníci zneužívají k phishingu.
Kontrolní seznam ladění
Pokud adresa URL nefunguje podle očekávání, zkontrolujte tyto položky v tomto pořadí:
- Hledejte %25— označuje dvojité kódování
- Kontrola + vs %20— jsou prostory ošetřovány důsledně?
- Zkontrolujte nezpracovaný požadavek— použijte v prohlížeči kartu DevTools Network k zobrazení skutečné odeslané zakódované adresy URL
- Test se speciálními znaky— zkusit
& = ? # /v hodnotách, abyste zjistili, zda narušují strukturu URL - Zkontrolujte Content-Type— je server analyzován jako
application/x-www-form-urlencodedneboaplikace/json? - Ověřte dekódování na serveru— protokolovat nezpracované a dekódované hodnoty na straně serveru
Bezpečné pomocné funkce
// Bezpečně vytvořte řetězec dotazu
function buildQueryString(params) { return Object.entries(params) .map(([klíč, hodnota]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}` ) .join('&');
} // Použijte URLSearchParams (moderní prohlížeče + Node.js)
const params = new URLSearchParams({ q: 'tom & jerry', stránka: '1' });
const url = `https://api.example.com/search?${params}`;
// Správně: kódování zpracovává automaticky
Nejlepší postup: Použití URLSearchParams nebo URL konstruktor namísto ručního zřetězení řetězců. Ve výchozím nastavení zpracovávají kódování správně.
FAQ
Proč se + stává prostorem?
Toto je dědictví z kódování formulářů HTML (application/x-www-form-urlencoded), kde jsou mezery zakódovány jako +. Ve standardním kódování procent (RFC 3986) jsou mezery %20. The + konvence platí pouze pro řetězce dotazů při odesílání formulářů, nikoli pro segmenty cest nebo jiné části URL.
Jak správně zakóduji vnořené adresy URL?
Použití encodeURIComponent na vnitřní URL před jeho umístěním do parametru dotazu vnější URL. Toto kóduje znaky jako :/? které by jinak byly interpretovány jako součást struktury vnější adresy URL.
Proč se podpisy po zakódování URL zlomí?
Podpisy se počítají přes přesné sekvence bajtů. Pokud podepíšete řetězec před kódováním (nebo po dekódování), ale ověříte jej v zakódované podobě (nebo naopak), bajty se liší a podpis se nezdaří. Před podpisem vždy normalizujte kódování.
Související nástroje a články
- URL kodér/dekodér— Testování kódování v reálném čase
- Bezpečnostní chyby JWT— také záleží na kódování pro manipulaci s tokeny
- Oprava nesouladu kontrolního součtu— při kódování změn poškozený hash souboru