Chyby v kódovaní URL, ktoré vývojári stále robia (a opravujú)

Chyby v kódovaní adries URL sú jemné, trvalé a často sa objavujú vo výrobe. A nesprávne umiestnený %20, dvojito zakódovaný ampersand alebo zmätený + vs priestor môže prerušiť volania API, poškodiť údaje sledovania a vytvoriť slabé miesta v zabezpečení. Poďme opraviť tie najbežnejšie.
Otestujte svoje kódovanie pomocou nášho Kódovač/dekodér URL nástroj — vložte ľubovoľný reťazec a okamžite uvidíte zakódovaný výsledok.
encodeURI vs encodeURIComponent
JavaScript má dve vstavané funkcie kódovania a použitie nesprávnej je zdrojom chýb č. 1:
| Funkcia | Kóduje | Konzervy | Použiť pre |
|---|---|---|---|
encodeURI | Medzery, iné ako ASCII | : / ? # [ ] @ ! $ & ' ( ) * + , ; = | Kódovanie úplnej adresy URL |
encodeURIComponent | Všetko nad +: / ? # @ ! $ & ' ( ) * + , ; = | Iba - _ . ~ a alfanumerické | Kódovanie hodnoty parametra dopytu |
// ZLE — encodeURI zachováva & v hodnotách dotazu
const url = 'https://api.example.com/search?q=' + encodeURI('tom & jerry');
// Výsledok: https://api.example.com/search?q=tom%20&%20jerry
// & je zachované — teraz to vyzerá ako samostatný parameter! // SPRÁVNE
const url = 'https://api.example.com/search?q=' + encodeURIComponent('tom & jerry');
// Výsledok: https://api.example.com/search?q=tom%20%26%20jerry
Základné pravidlo: Použite encodeURIComponent pre jednotlivé hodnoty. Použite encodeURI iba vtedy, keď máte úplnú adresu URL, ktorá potrebuje zakódovať iba znaky iné ako ASCII.
Chyby dvojitého kódovania
K dvojitému kódovaniu dôjde, keď sa už zakódovaný reťazec znova zakóduje:
const name = 'ahoj svet';
const encoded = encodeURIComponent(meno); // ahoj%20world
const doubled = encodeURIComponent(encoded); // ahoj%2520svet
// %25 je kódovanie samotného %!
K tomu zvyčajne dochádza, keď:
- Rámec automaticky kóduje parametre dopytu a vy ich tiež vopred zakódujete
- Adresa URL sa pred uložením zakóduje a pri získaní sa znova zakóduje
- Middleware spracováva URL vo viacerých vrstvách, pričom každá pridáva kódovanie
Detekcia
Hľadajte %25 v URL — je to takmer vždy znak dvojitého kódovania. Postupnosť %2520(dvojito zakódovaný priestor) je klasický oznamovač.
Zmätok + vs %20
V odoslaných formulároch HTML (application/x-www-form-urlencoded), medzery sa stávajú +. V štandardnom kódovaní percent (RFC 3986) sa medzery stávajú %20.
Toto je dôležité, pretože:
decodeURIComponentrobí nie dekódovať+späť do vesmíru – opúšťa ho ako doslov+- Backendové rámce môžu alebo nemusia automaticky dekódovať
+v závislosti od analyzátora - Ak vaše API očakáva
%20ale prijíma+, hľadá „červené+auto“ a vráti výsledky pre „červené+auto“ (s doslovným plusom) namiesto „červené auto“
// Bezpečné dekódovanie, ktoré zvládne + aj %20
function safeDecodeParam(value) { return decodeURIComponent(value.replace(/\+/g, '%20'));
} Puzdrá na okraje UTF-8
Znaky iné ako ASCII, napr é, ü, 日本語 a emotikony musia byť zakódované v percentách ako ich sekvencie bajtov UTF-8:
encodeURIComponent('café') // caf%C3%A9
encodeURIComponent('日本語') // %E6%97%A5%E6%9C%AC%E8%AA%9E
encodeURIComponent('🔒') // %F0%9F%94%92
Problémy vznikajú, keď:
- Server očakáva Latin-1, ale dostane UTF-8 (mojibake – skomolené znaky)
- Stĺpce databázy nie sú nastavené na UTF-8, takže sa ticho skracujú viacbajtové znaky
- Protokolové súbory interpretujú zakódované reťazce s nesprávnou znakovou sadou
Úskalia adresy URL s presmerovaním a spätným volaním
Spätné volania a presmerovania OAuth sú obzvlášť náchylné na chyby kódovania:
// Vytvorenie presmerovania OAuth
const redirectUri = 'https://myapp.com/callback?source=oauth';
const authUrl = `https://provider.com/auth?redirect_uri=${encodeURIComponent(redirectUri)}`;
// Správne: celá adresa URL spätného volania (vrátane jej vlastného ?) je zakódovaná ako hodnota jedného parametra
Časté chyby:
- Nekódovanie
redirect_urivôbec — ten?v spätnom volaní rozdelí nadradenú adresu URL - Kódovanie
redirect_uričiastočne – kódovanie cesty, ale nie dotazu - Kódovanie celej overovacej adresy URL namiesto iba hodnoty parametra
Tieto chyby často vytvárajú zraniteľné miesta s otvoreným presmerovaním, ktoré útočníci využívajú na phishing.
Kontrolný zoznam ladenia
Ak adresa URL nefunguje podľa očakávania, skontrolujte tieto položky v tomto poradí:
- Vyhľadajte %25— označuje dvojité kódovanie
- Kontrola + vs %20— sú priestory spravované dôsledne?
- Skontrolujte nespracovanú požiadavku— použite kartu DevTools Network v prehliadači na zobrazenie skutočne odoslanej zakódovanej adresy URL
- Test so špeciálnymi znakmi— skúsiť
& = ? # /v hodnotách, aby ste zistili, či neporušujú štruktúru adresy URL - Skontrolujte typ obsahu— je server analyzujúci ako
application/x-www-form-urlencodedaleboapplication/json? - Overte dekódovanie na serveri— zaznamenajte nespracované a dekódované hodnoty na strane servera
Bezpečné pomocné funkcie
// Bezpečne vytvorte reťazec dotazu
function buildQueryString(params) { return Object.entries(params) .map(([kľúč, hodnota]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}` ) .join('&');
} // Použite URLSearchParams (moderné prehliadače + Node.js)
const params = new URLSearchParams({ q: 'tom & jerry', strana: '1' });
const url = `https://api.example.com/search?${params}`;
// Správne: spracuje kódovanie automaticky
Osvedčený postup: Použite URLSearchParams alebo URL konštruktor namiesto manuálneho zreťazenia reťazcov. Štandardne zvládajú kódovanie správne.
FAQ
Prečo sa + stáva priestorom?
Toto je dedičstvo z kódovania formulárov HTML (application/x-www-form-urlencoded), kde sú medzery zakódované ako +. V štandardnom kódovaní percent (RFC 3986) sú medzery %20. The + konvencia sa vzťahuje iba na reťazce dopytov pri odosielaní formulárov, nie na segmenty cesty alebo iné časti adresy URL.
Ako správne zakódujem vnorené adresy URL?
Použite encodeURIComponent na vnútornej adrese URL pred umiestnením do parametra dopytu vonkajšej adresy URL. Toto kóduje znaky ako :/? ktoré by sa inak interpretovali ako súčasť štruktúry vonkajšej adresy URL.
Prečo sa podpisy po zakódovaní adresy URL zlomia?
Podpisy sa počítajú cez presné sekvencie bajtov. Ak podpíšete reťazec pred zakódovaním (alebo po dekódovaní), ale overíte ho v zakódovanej forme (alebo naopak), bajty sa líšia a podpis zlyhá. Pred podpisom vždy znormalizujte kódovanie.
Súvisiace nástroje a články
- Kódovač/dekodér URL— testovanie kódovania v reálnom čase
- Bezpečnostné chyby JWT— záležitosti týkajúce sa kódovania aj pri manipulácii so symbolmi
- Oprava nesúladu kontrolného súčtu— pri zmenách kódovania poškodené hodnoty hash súborov