Százalékos kódolás-vizsgáló

A százalékos kódolás nem egyetlen szabály, hanem több, és tucatnyi karakternél nem értenek egyet. Ez az oldal ugyanazt a szöveget egymás mellett futtatja az encodeURIComponent, az encodeURI és az application/x-www-form-urlencoded sorosítással, megjelöli azokat a karaktereket, ahol eltérnek, karakterenként egy sort ír ki az UTF-8 bájtjaival és az RFC 3986 osztályával, és megmondja, hányszor kódolták már a sztringet. A dekódolási oldal a sztringet szigorú vagy engedékeny szabály szerint olvassa, és megmondja, melyik escape hibás és hol, ahelyett hogy csendben hibás eredményt adna vissza.
Minden feldolgozás helyben, a böngészőben történik — az adatok soha nem kerülnek feltöltésre semmilyen szerverre.

Nem tudja, mi a százalékos kódolás? A százalékos kódolás közérthetően — mi ez, miért lesz a szóközből %20 vagy +, és mit jelent, ha egy URL %25-öt mutat.
Mit csinál ez:
Hogyan olvassuk az escape-eket:
encodeURIComponent
encodeURI
űrlap (application/x-www-form-urlencoded)
A Ctrl+Enter a bemenetben futtatja az aktív módot.
Mód választható, és a hozzá tartozó művelet gombbal indítható a feldolgozás. Az Kódolás & vizsgálat a szöveg három kódolását mutatja, plusz karakterenként egy sort; a Dekódolás visszaolvassa az escape-eket, és megszámolja a rétegeket. Az Önellenőrzés gomb újrafuttatja az adatfájlban rögzített összes dokumentált mintát, minden nyomtatható ASCII karaktert és az ott rögzített rétegláncokat, és az eredmény számát itt jeleníti meg.
Ahol a kódolók nem értenek egyet:csak az alábbi karaktereket kezeli a három módszer eltérően. Minden más mindhárom módszeren változatlanul átmegy, vagy mindhárom ugyanúgy escape-eli.
Minden karakter, soronként egy:a karakter UTF-8 bájtjai, az RFC 3986 osztálya, és az escape, amelyet minden kontextus ír. A négy kontextusoszlop a WHATWG URL százalékos kódolási készletei, amelyeket a böngésző az útvonal, lekérdezés vagy fragmentum összeállításakor használ; az árnyékolt sor olyan karakter, amelyet a három kódoló eltérően kezel.
Az a pontos készlet, amelyet ez az oldal URL-rész szerint escape-el:magából a kódolóból íródik, így ez a táblázat és az oszlopokat kitöltő kód nem térhet el egymástól. Minden készlet escape-eli a C0-vezérlőkarakterek (U+0000–U+001F) és minden U+007E feletti kódpont, ezért a nem ASCII szöveg minden kontextusban escape-elődik.
Ezek a készletek a WHATWG százalékos kódolási készletekből származnak, és két szándékos helyen térnek el tőlük, mindkettő a kézi összeállítást teszi biztonságossá: a kettőskeresztet a lekérdezésen belül escape-eli, mert a nyers kettőskereszt elkezdené a fragmentumot; a komponens-készlet pedig pontosan az encodeURIComponent által escape-elt karakterekre van rögzítve, az aposztrófot is beleértve, míg az űrlapkészlet az URLSearchParams által escape-eltekre. A fenti táblázat két oszlopa tehát a platform saját viselkedése, nem annak újraimplementálása. Ez a lista magyarázza az emberek számára meglepő eredményt is: a százalékjelet az encodeURIComponent és az encodeURI is escape-eli, de a WHATWG kontextus-készletek egyikében sem szerepel, ezért a karakterenkénti táblázat útvonal-, lekérdezés- és fragmentum-oszlopa békén hagyja. A kézzel összeállított URL-ben a nyers százalékjel így is kockázat, mert a szabvány elvárja, hogy a bemenetet előbb ellenőrizzék: a %41 lekérdezésen belül sok szerverkeretrendszernek egyetlen A, és az oldal saját szigorú olvasata egyedülálló %-t hibás escape-nek tekint. Az általa escape-elése %25-ként a biztonságosabb szokás, és a karakterenkénti táblázat mindkét írásmódot egymás mellett mutatja.
Hányszor kódolták már ezt a sztringet:a dekódolás minden köre egy réteg. A kétszer kódolt érték ezzel kezdődik:%25ahol egy egyszeri kódolás hagyna%20, és a háromszor kódolt érték ezzel kezdődik:%2525.
Azok a karakterek, amelyeket egy URL változatlanul hordozhat:Az RFC 3986 az ASCII-tartományt három csoportra osztja, és az escape-szabályok csak ehhez a felosztáshoz képest értelmesek.
A fenntartott karakterek nincsenek tiltva, hanem foglaltak: a URL-elemző számára jelentésük van. A listából következő szabály rövid: ha egy karakter fenntartott, és adatként gondolják, escape-elni kell; ha fenntartatlan, soha nincs rá szükség.
A három módszer, és hogy mit hagy békén mindegyik:
A listák pontosan azok a készletek, amelyeket minden módszer az ASCII-tartományban escape-elés nélkül hagy; az Önellenőrzés minden nyomtatható ASCII karaktert ellenőriz velük szemben, így a táblázat nem térhet el a leírt kódolóktól.
Mekkora bemenetet fogad el ez az oldal, és miért:A százalékos kódolás egyetlen menetben fut a szövegen, így a költség a rádix-átalakítóktól eltérően egyenesen nő, nem négyzetesen: nincs olyan hossz, ahol az aritmetika lenne a probléma. A lenti korlátok azért vannak, mert a karakterenkénti táblázat a dokumentumban jelenik meg, és egymillió sort tartalmazó táblázat az, ami valóban megállítja a böngészőt.
Mi a százalékos kódolás?

A százalékos kódolás — URL-kódolásnak is nevezik, a régebbi dokumentumokban escape-elésnek — az a szabály, amely lehetővé teszi, hogy az URL olyan karaktereket hordozzon, amelyeket nem tartalmazhatna. Egy százalékos escape három ASCII-karakter: egy százalékjel és két hexadecimális számjegy, amely egy bájtot jelöl. A %20 a 0x20 bájt, vagyis szóköz. A %2F a 0x2F bájt, vagyis perjel. Más nincs benne: az escape bájtot nevez meg, nem karaktert.

Mivel bájtokat nevez meg, a szöveget először bájtokká kell alakítani, és a bájtkódolás az UTF-8. Innen erednek a hosszú escape-ek: egy kínai karakter három UTF-8 bájt, tehát három escape, egy emoji pedig négy bájt, azaz tizenkét ASCII-karakter.

A 30 másodperces változat: a szóköz URL-értékként %20, űrlapadatban viszont +; a # %23; a szó szerinti százalékjel %25. Az oldal három kódolója egyetért a betűkben, a számjegyekben és a -_. karakterekben, és tucatnyi írásjelnél eltér egymástól — köztük a tildénél —, ezért az encodeURIComponent és az encodeURI ugyanarra a szövegre más sztringet ad, és a rossz kettő valamelyike egy értéket két lekérdezési paraméterre bonthat.
Miért van egyáltalán szüksége erre az URL-nek

Az URI az ASCII-karakterek sorozataként definiált (RFC 3986 2.1 szakasz), és ezen az ASCII-tartományon belül egyes karakterek fenntartottak: ezek az URL szerkezetét adó írásjelek. A kettőspont és a két perjel választja el a sémát, a kukac a felhasználói információt a gazdagéptől, a kérdőjel a lekérdezést kezdi, a kettős kereszt a fragmentumot, az és-jel a lekérdezési paramétereket választja el, a százalékjel pedig escape-et vezet be.

Ez egy problémát és egy kiskaput hoz létre. A probléma: egy érték, amely is tartalmazza ezek egyikét — egy keresőmező a „a&b” szöveggel, egy perjelet tartalmazó fájlnév, kettőspontot tartalmazó jelszó — egyébként megváltoztatná annak az URL-nek a szerkezetét, amelyben utazik. A kiskapu a százalékjel, így a kódoló egyszerűen kiterjesztheti az ábécéjét. A % %25-ként íródik, és az utána álló két hexadecimális számjegy közönséges fenntartatlan karakter.

Kidolgozott példák

Ez a három kódoló pontos kimenete, amelyet ez az oldal futtat, olyan bemeneteken, amelyeket azért választottak, mert másként viselkednek egymáshoz képest. Az oldal megjelenítéskor újra kiszámolja őket, az Önellenőrzés pedig minden sort összevet a platform saját implementációival.

A három módszer, és mikor melyik a helyes

A rövid változat, amely a legtöbb hibát megelőzi: minden, ami egyetlen paraméterértékbe kerül, az encodeURIComponent-en megy át (vagy egy űrlapsorosítón, amely ugyanezt a munkát végzi más biztonságos készlettel), és egy már összeállított teljes URL az encodeURI-n megy át, ha egyáltalán escape-elni kell. A két függvény közül a rosszat választani a webkódban a legelterjedtebb százalékos kódolási hiba.

Az URL-ben szerepelhető karakterek teljes listája
Két pluszjel, két jelentés

A szóköz az egyetlen karakter, amelynek kódolása attól függ, hová tart a szöveg, és a pluszjel az oka.

A csapda a táblázat közepén van. Űrlapadatban a pluszjel szóközt jelent, így egy valóban pluszjelet tartalmazó értéket — telefonszám +44 20 7946 0958 formában, aritmetikai kifejezést, pluszcímkés e-mail-címet — %2B-ként kell továbbítani. Ha szó szerinti pluszjelként utazik, a fogadó szóközként olvassa vissza, és a +44 „ 44”-ként érkezik.

Kétszer kódolva, és így ismerhető fel

Kettős kódolás akkor történik, ha egy sztring már escape-elt, és újra escape-elik. Az első escape százalékjele is egy karakter, így %25 lesz belőle, és az alatta lévő réteg látható szövegként megmarad.

Felismerése számolás kérdése: egyszer dekódolja a sztringet, és nézi az eredményt. Ha még mindig olyan escape-eket tartalmaz, amelyek szándékosnak látszanak — érvényes %XX, vagy űrlap-pluszjel ott, ahol szóközt várnánk —, akkor van még egy réteg. Ha %25 után két hexadecimális számjegy áll, a következő réteg biztosan escape.

Két gyakorlati megjegyzés. Először: a kétszeri dekódolás nem ártalmatlan: jól ismert módja annak, hogy egy biztonsági szűrő és a mögötte lévő kód más sztringeket lásson, ezért az a szűrő, amely a második dekódolás előtt fut, rossz szöveget szűr. Másodszor: a rétegszám itt a sztring tulajdonsága, nem a szándékra vonatkozó ígéret: egy jogos érték lehet egyetlen rétegű, egy hibás pedig kettős.

A hibák, amelyeket ez az oldal felismerni hivatott
  • Az encodeURI-val kódolt érték. Az elválasztók megmaradnak, így az & vagy = jelet tartalmazó érték a másik oldalon több paraméterre bomlik. Az oldal tetején lévő két oszlopot hasonlítsa össze az a&b=c bemeneten: a komponens-oszlop mindkét karaktert escape-eli, az encodeURI-oszlop megtartja őket.
  • Űrlapadatként küldött szó szerinti pluszjel. Szóközként érkezik. A %2B használandó.
  • Érték kétszer escape-elve, „a biztonság kedvéért”. Nem biztonságosabb. A fogadó egyszer dekódol, és olyan sztringet kap, amely még mindig százalékos escape-eket tartalmaz, ez ugyanaz a hiba, mint a rossz karakterkészlet, eggyel mélyebb rétegben.
  • Olyasmit dekódolni, amit soha nem kódoltak. A szövegben lévő szó szerinti százalékjel — 100% sure — nem escape. Szigorú olvasatban hibás escape, az oldal által jelzett helyen; engedékeny olvasatban megmarad, ezért az engedékeny az alapértelmezett, és nem fordítva.
  • Azt feltételezni, hogy az escape-nek nagybetűsnek kell lennie. A dekódolás a %2f-t és a %2F-et ugyanazon bájtként kezeli, és mindkettő érvényes. A nagybetű csak az a kanonikus írásmód, amelyet az RFC 3986 ajánl, és amelyet más eszközök előállítanak.
  • Azt feltételezni, hogy a százalékos kódolás biztonságossá teszi a szöveget. Egyértelművé teszi a szöveget az URL-en belül. Nem állítja meg az injektálást, nem titkosítás, és nem fertőtlenítő: az escape-elésnek az összeállítás előtti utolsó lépésnek kell lennie, arra a kontextusra, amelybe a szöveg kerül.
Gyors válaszok

“URL-ben a pluszjel szóköz?”

Csak űrlapadatban, és csak egy űrlapküldés lekérdezési részében. Útvonalban, fragmentumban és egy sima link lekérdezésében a pluszjel szó szerinti pluszjel. Ezért van erre az oldalon kapcsoló, és nem találgatásra támaszkodik.

“Miért mutat a linkem %25-öt?”

Mert valami kódolt egy százalékjelet. Vagy egy szó szerinti százalékjel ment át egy kódolón — a 100% sure 100%25%20sure lesz —, vagy egy már escape-et tartalmazó sztringet kódoltak másodszor. A sztring egyszer dekódolható, és megnézhető, mi jön vissza: ha az eredmény még mindig %XX-et tartalmaz, van még egy réteg.

“Számít-e, hogy a lekérdezési érték belsejében lévő perjel %2F vagy /?”

Az URL-elemzőnek nem: mindkettő perjelként jut el a szerverhez, a WHATWG lekérdezési készlet pedig a perjelet békén hagyja. Az együttműködésnek néha igen: sok szerverkeretrendszer saját dekódolást futtat egy nyers lekérdezési sztringen, és néhány eltér azoknál a karaktereknél, amelyeket soha nem escape-eltek. Ha egy értéket kézzel állítanak össze sorosító helyett, a fenntartott karakterek kifejezett escape-elése a biztonságosabb szokás.

“Miért kódolja az űrlaposzlop a tildét, amelyet a másik kettő békén hagy?”

Mert az űrlapkódoló biztonságos készlete szűkebb: csak betűk, számjegyek és -_.*. A WHATWG űrlapkódoló a ~ ! ' ( ) karaktereket escape-eli, pedig az RFC 3986 a ~-t fenntartatlannak tartja. Mindkét írásmód ugyanazt az értéket dekódolja; a különbség csak akkor számít, ha a sztringeket bájtonként hasonlítjuk össze.

“Megjelenhetnek ugyanezek a karakterek escape nélkül a böngésző címsorában?”

Igen, és ez a címsor, nem az URL. A böngészők az URL olvasható alakját mutatják, és küldéskor kódolják, így a linkben lévő 中文 a vezetéken %E4%B8%AD%E6%96%87 lesz. Ha az URL-t a címsorból másolja ki, böngészőtől függően bármelyik alakot kaphatja.

“Minden escape érvényesnek látszik, mégis nem azt a karaktert kapom, amit vártam. Miért?”

A "rosszul dekódolódott" mögött két különböző hiba rejtőzik, és az oldal másként jelenti őket. Az első egy hibás escape: olyan százalékjel, amelyet nem két hexadecimális számjegy követ, például egy végső 100% vagy egy %zz. Ez szintaktikai probléma: a szigorú olvasat elutasítja és megmondja, hol van, az engedékeny olvasat szó szerinti szövegként megtartja és felsorolja. A második egy escape, amelynek bájtja teljesen legális, de a bájtok nem alkotnak érvényes UTF-8 karaktert, például egyedül álló %FF vagy egy háromBájtos karakter csonkolva %E4%B8. Ez nem szintaktikai probléma, ezért mindkét olvasat visszaadja a szöveget, a dekódolhatatlan bájtokat pótkarakterrel, a U+FFFD-del ("�") helyettesíti, és figyelmeztetést ír erről. Ez a figyelmeztetés a hasznos rész: a pótkarakterekben érkező szöveg általában azt jelenti, hogy a feladó másik karakterkészletet használt, vagy hogy a sztring egyszerrel többet lett escape-elve. A százalékos kódolás bájtokat nevez meg, és ez az oldal, akárcsak az URL-szabvány, ezeket a bájtokat mindig UTF-8-ként olvassa.

“Mit nem csinál ez az oldal?”

Nem bontja fel az URL-t sémára, gazdagépre, útvonalra és lekérdezésre — erre való az URL-elemző. Nem ellenőrzi, biztonságos-e megnyitni a linket, nem kapcsolódik semmihez, és nem találgatja az escape mögötti bájtok karakterkészletét: mindig UTF-8-ként olvassa őket, ahogy az URL-szabvány előírja.

“Milyen visszalépés kell a dekódoláshoz, és honnan tudom, hogy helyes?”

az Önellenőrzés gomb megnyomható. Összehasonlítja az oldal saját kódolóit a platform encodeURIComponent, encodeURI és URLSearchParams függvényével minden nyomtatható ASCII karakterre, újrafuttatja a fenti táblázatok minden példáját, újraellenőrzi a rögzített rétegláncokat, és az ellenőrzések számát itt jelenti.

Szabványok és hatókör

A százalékos kódolást az RFC 3986 2.1 szakasza írja le, a fenntartott és fenntartatlan karakterek definícióját a 2.2 és 2,3 szakasz, a kis- és nagybetű szabályát a 6.2.2.1 szakasz. Azokat a készleteket, amelyeket a böngésző valójában használ az URL felépítésekor, a WHATWG URL-szabvány adja meg, kontextus szerint felosztva: külön készlet a fragmentumnak, a lekérdezésnek, a speciális lekérdezésnek, az útvonalnak, a felhasználói információnak, és a szűkebb egyetlen komponensnek. Az űrlapküldés, a pluszjellel együtt, a HTML-szabványban van, az application/x-www-form-urlencoded alatt. Az encodeURI és az encodeURIComponent függvények az ECMAScript részei.

Az oldal az útvonal-, lekérdezés- és fragmentum-oszlopokat a saját kontextus-készleteivel tölti ki, és minden kontextus pontos listáját az eredmény mellett írja ki. Ezek a készletek a WHATWG-készletekből származnak, és két szándékos helyen térnek el tőlük: a kettőskeresztet a lekérdezésen belül escape-eli, mert egy nyers kettőskereszt elkezdené a fragmentumot, a komponens-készlet pedig pontosan azokra a karakterekre van rögzítve, amelyeket az encodeURIComponent escape-el. Ahol egy platformfüggvény a válasz definíciója — az encodeURIComponent, az encodeURI és az űrlapsorosítás —, azt a függvényt közvetlenül hívjuk, így ezek az oszlopok a böngésző saját viselkedését mutatják, nem annak újraimplementálását.

A szöveg ehhez a webhelyhez íródott. A fenti táblázatok minden értékét az oldal saját kódja állítja elő betöltéskor, és a webhely tesztelő eszközeiben a platform implementációival ellenőrizték; az Önellenőrzés ugyanezt az összehasonlítást megismétli a böngészőben.