Prosenttikoodauksen tarkastaja

Prosenttikoodaus ei ole yksi sääntö vaan useita, ja ne ovat eri mieltä noin tusinasta merkistä. Tämä sivu ajaa saman tekstin encodeURIComponent-, encodeURI- ja application/x-www-form-urlencoded-sarjoituksen rinnakkain, merkitsee merkit, joissa ne eroavat, tulostaa rivin per merkki sen UTF-8-tavuilla ja RFC 3986 -luokalla ja kertoo, kuinka monta kertaa merkkijono on koodattu. Purkupuoli lukee merkkijonon tiukalla tai löysällä säännöllä ja kertoo, mikä escape on rikki ja missä, sen sijaan että palauttaisi hiljaa väärän tuloksen.
Kaikki käsittely tapahtuu paikallisesti selaimessa — tietoja ei lähetetä mihinkään palvelimelle.

Etkö ole varma, mitä prosenttikoodaus on? Prosenttikoodaus selitettynä yksinkertaisesti — mitä se on, miksi välilyönti muuttuu muotoon %20 tai +, ja mitä se tarkoittaa, kun URL-osoitteessa näkyy %25.
Mitä tämä tekee:
Miten escapet luetaan:
encodeURIComponent
encodeURI
lomake (application/x-www-form-urlencoded)
Ctrl+Enter syötteessä suorittaa aktiivisen tilan.
Valitse tila ja napsauta sen toimintopainiketta. Koodaa ja tarkastele näyttää tekstin kolme koodausta sekä rivin per merkki; Pura lukee escapet takaisin ja laskee kerrokset. Itsetestipainike ajaa uudelleen jokaisen dokumentoidun esimerkin, jokaisen tulostettavan ASCII-merkin ja tämän sivun tietotiedostoon kirjatut kerrosketjut, ja raportoi määrän tässä.
Kohdat, joissa koodaimet ovat eri mieltä:Vain alla luetellut merkit käsitellään kolmella menetelmällä eri tavoin. Kaikki muu kulkee kaikkien kolmen läpi muuttumattomana tai kaikki kolme escapeavat sen samalla tavalla.
Jokainen merkki, yksi rivi kullekin:merkin muodostamat UTF-8-tavut, luokka, jonka RFC 3986 antaa sille, ja escape, jonka kukin konteksti kirjoittaa. Neljä kontekstisaraketta ovat WHATWG-URL-osoitteen prosenttikoodausjoukkoja, joita selain käyttää polun, kyselyn tai fragmentin rakentamiseen; harmaaksi varjostettu rivi on merkki, jota kolme koodainta käsittelevät eri tavoin.
Tarkka joukko, jonka tämä sivu escapeaa URL-osoitteen kullekin osalle:tulostettu itse koodaimesta, joten tämä taulukko ja sarakkeet yllä täyttävä koodi eivät voi erkaantua toisistaan. Jokainen joukko escapeaa myös C0-ohjausmerkit (U+0000–U+001F) ja jokaisen koodipisteen yli U+007E:n, minkä vuoksi ei-ASCII-teksti escapeataan aina kaikissa konteksteissa.
Nuo joukot on johdettu WHATWG:n prosenttikoodausjoukoista ja eroavat niistä kahdessa tarkoituksellisessa kohdassa, jotka molemmat tekevät käsin kokoamisesta turvallista: risuaita escapeaan kyselyn sisällä, koska raaka risuaita aloittaisi fragmentin; ja komponenttijoukko on lukittu täsmälleen niihin merkkeihin, joita encodeURIComponent escapeaa, heittomerkki mukaan lukien, kun lomakejoukko on lukittu siihen, mitä URLSearchParams escapeaa. Yllä olevan taulukon kaksi saraketta ovat siis alustan omaa toimintaa eivätkä sen uudelleentoteutusta. Sama luettelo selittää tuloksen, jonka ihmiset kokevat yllättävänä: encodeURIComponent ja encodeURI escapeavat prosenttimerkin, mutta se ei kuulu yhteenkään WHATWG-kontekstijoukkoon, joten merkkikohtaisen taulukon polku-, kysely- ja fragmenttisarakkeet jättävät sen rauhaan. Raaka prosenttimerkki käsin kootussa URL-osoitteessa on silti riski, koska standardi odottaa syötteen validoidun ensin: %41 kyselyn sisällä on yksi A monille palvelinkehyksille, ja tämän sivun oma tiukka lukutapa käsittelee yksinäisen %-merkin rikkinäisenä escapena. Sen escapeaminen itse muodossa %25 on turvallisempi tapa, ja merkkikohtainen taulukko näyttää molemmat kirjoitusasut rinnakkain.
Kuinka monta kertaa tämä merkkijono on koodattu:jokainen purkukierros on yksi kerros. Arvo, joka on koodattu kahdesti, alkaa%25missä yksi koodaus jättäisi%20ja arvo, joka on koodattu kolmesti, alkaa%2525.
Merkit, jotka URL-osoite voi kantaa sellaisinaan:RFC 3986 jakaa ASCII-alueen kolmeen ryhmään, ja escape-säännöt ovat järkeviä vain tätä jakoa vasten.
Varatut merkit eivät ole kiellettyjä, ne ovat varattuja: ne merkitsevät jotain URL-jäsentimelle. Luettelosta seuraa lyhyt sääntö — jos merkki on varattu ja tarkoitat sen dataksi, escapeaa se; jos se on varaamaton, sitä ei koskaan tarvitse escapeata.
Kolme menetelmää ja se, mitä kukin jättää rauhaan:
Luettelot ovat tarkat joukot, jotka kukin menetelmä jättää escapeamatta ASCII-alueella; Itsetesti tarkistaa jokaisen tulostettavan ASCII-merkin niitä vasten, joten taulukko ei voi erkaantua koodaimista, joita se kuvaa.
Kuinka suuren syötteen tämä sivu hyväksyy ja miksi:prosenttikoodaus on yksi kierros tekstin yli, joten toisin kuin tämän sivuston kantamuunnin, kustannus kasvaa suoraviivaisesti eikä neliöllisesti: ei ole pituutta, jolla itse laskenta muuttuisi ongelmaksi. Alla olevat rajat ovat olemassa, koska merkkikohtainen taulukko piirretään dokumenttiin, ja miljoonan rivin taulukko on se, mikä oikeasti pysäyttää selaimen.
Mikä on prosenttikoodaus?

Prosenttikoodaus — kutsutaan myös URL-koodaukseksi ja vanhemmissa asiakirjoissa escapeksi — on sääntö, joka antaa URL-osoitteen kantaa merkkejä, joita sillä ei saisi olla. Prosentti-escape on kolme ASCII-merkkiä: prosenttimerkki ja kaksi heksanumeroa, jotka tarkoittavat yhtä tavua. %20 on tavu 0x20, eli välilyönti. %2F on tavu 0x2F, eli kauttaviiva. Muuta ei ole: escape nimeää tavun, ei merkkiä.

Koska se nimeää tavuja, teksti on ensin muutettava tavuiksi, ja tavukoodaus on UTF-8. Siitä pitkät escapet tulevat: yksi kiinalainen merkki on kolme UTF-8-tavua ja siten kolme escapea, ja yksi emoji on neljä tavua ja kaksitoista ASCII-merkkiä.

Lyhyt versio: välilyönti on URL-arvossa %20 mutta lomakedatassa +; # on %23; kirjaimellinen prosenttimerkki on %25. Tämän sivun kolme koodainta ovat samaa mieltä kirjaimista, numeroista ja -_.-merkeistä, ja ne ovat eri mieltä noin tusinasta välimerkistä, tilde mukaan lukien — juuri siksi encodeURIComponent ja encodeURI tuottavat eri merkkijonon samalle tekstille, ja väärä niistä voi jakaa arvon kahdeksi kyselyparametriksi.
Miksi URL tarvitsee sitä ollenkaan

URI määritellään ASCII-merkkien sarjana (RFC 3986 -kohta 2.1), ja tuon ASCII-alueen sisällä osa merkeistä on varattuja: ne ovat välimerkkejä, jotka antavat URL-osoitteelle sen rakenteen. Kaksoispiste ja kaksi kauttaviivaa erottavat skeeman, @-merkki erottaa käyttäjätiedot isännästä, kysymysmerkki aloittaa kyselyn, risuaita aloittaa fragmentin, &-merkki erottaa kyselyparametrit, ja prosenttimerkki johdattaa escapen.

Se luo yhden ongelman ja yhden aukon. Ongelma: arvo, joka sisältää itsessään yhden noista merkeistä — hakukenttä, jossa on "a&b", tiedostonimi kauttaviivalla, salasana kaksoispisteellä — muuttaisi muuten URL-osoitteen rakennetta, jossa se kulkee. Aukko: prosenttimerkki itse, joten koodain voi yksinkertaisesti laajentaa omaa aakkostoaan. % kirjoitetaan muodossa %25, ja sen jälkeiset kaksi heksanumeroa ovat tavallisia varaamattomia merkkejä.

Esimerkkejä

Nämä ovat niiden kolmen koodaimen tarkkoja tuloksia, joita tämä sivu ajaa, syötteillä, jotka on valittu, koska ne käyttäytyvät eri tavoin. Sivu laskee ne uudelleen näkyviin, ja sen Itsetesti tarkistaa jokaisen rivin alustan omia toteutuksia vastaan.

Kolme menetelmää ja milloin kukin on oikea

Lyhyt versio, joka säästää useimmat virheet: kaikki, mikä menee yhteen parametriarvoon, kulkee encodeURIComponent-funktion läpi (tai lomakesarjoittajan, joka tekee saman työn eri turvallisella joukolla), ja valmiiksi kootun täydellisen URL-osoitteen, joka tarvitsee escapeja lainkaan, kulkee encodeURI-funktion läpi. Näiden kahden väärän valinta on web-koodin yleisin prosenttikoodausvirhe.

URL-osoite voi kantaa seuraavat merkit kokonaisuudessaan
Kaksi plusmerkkiä, kaksi merkitystä

Välilyönti on ainoa merkki, jonka koodaus riippuu siitä, mihin teksti on menossa, ja plusmerkki on syy siihen.

Ansa on tuon taulukon keskellä. Lomakedatassa plusmerkki tarkoittaa välilyöntiä, joten arvo, joka todella sisältää plusmerkin — puhelinnumero kirjoitettuna +44 20 7946 0958, laskulauseke, sähköpostiosoite plusmerkillä varustetulla tunnisteella — on kuljetettava muodossa %2B. Jos se kulkee kirjaimellisena plusmerkkinä, vastaanottaja lukee sen välilyöntinä, ja +44 saapuu muodossa " 44".

Kaksinkertaisesti koodattu ja miten sen tunnistaa

Kaksinkertainen koodaus tapahtuu, kun merkkijono on jo escapeoitu ja escapeoidaan sitten uudelleen. Ensimmäisen escapen prosenttimerkki on kuin mikä tahansa muu merkki, joten siitä tulee %25, ja sen alla oleva kerros säilyy näkyvänä tekstinä.

Tunnistaminen on laskemista: pura merkkijono kerran ja katso tulosta. Jos se sisältää yhä näyttävästi tarkoituksellisia escapeja — kelvollisen %XX-muodon tai lomakkeen plusmerkin siinä, missä odotetaan välilyöntiä — on vielä yksi kerros. Jos siinä on %25 ja sen perässä kaksi heksanumeroa, seuraava kerros on varmasti escape.

Kaksi käytännön huomiota. Ensinnäkin kahdesti purkaminen ei ole vaaratonta: se on tunnettu tapa saada turvasuodatin ja sen takana oleva koodi näkemään eri merkkijonoja, joten suodatin, joka ajetaan ennen toista purkua, suodattaa väärää tekstiä. Toiseksi kerrosluku tässä on merkkijonon ominaisuus, ei lupaus tarkoituksesta: laillinen arvo voi olla yhden kerroksen syvyinen ja rikkinäinen kaksi.

Virheet, joita tämä sivu on tehty havaitsemaan
  • Arvo koodattu encodeURI-funktiolla. Erottimet säilyvät, joten arvo, joka sisältää &- tai =-merkin, jakautuu toisella puolella useaksi parametriksi. Vertaa tämän sivun yläosan kahta saraketta syötteellä a&b=c: komponenttisarake escapeaa molemmat merkit, encodeURI-sarake säilyttää ne.
  • Kirjaimellinen plusmerkki lähetettynä lomakedatana. Se saapuu välilyöntinä. Käytä %2B.
  • Arvo escapeoitu kahdesti "varmuuden vuoksi". Se ei ole turvallisempi. Vastaanottaja purkaa kerran ja saa merkkijonon, joka sisältää yhä prosenttiescapeja - sama virhe kuin väärä merkistö, yhtä kerrosta alempana.
  • Sellaisen purkaminen, mitä ei ole koskaan koodattu. Kirjaimellinen prosenttimerkki tekstissä — 100% sure — ei ole escape. Tiukassa lukutavassa se on rikkinäinen escape siinä kohdassa, jonka tämä sivu raportoi; löysässä lukutavassa se säilyy, minkä vuoksi löysä on tämän sivun oletus eikä päinvastoin.
  • Oletus, että escapen on oltava isoilla kirjaimilla. Purku käsittelee %2f- ja %2F-muodot samana tavuna, ja molemmat ovat kelvollisia. Isot kirjaimet ovat vain RFC 3986:n suosittelema kanoninen kirjoitusasu, ja sen muut työkalut tuottavat.
  • Oletus, että prosenttikoodaus tekee tekstistä turvallisen. Se tekee tekstistä yksiselitteisen URL-osoitteen sisällä. Se ei estä injektiota, se ei ole salausta eikä puhdistusta: escapen on oltava viimeinen vaihe ennen kokoamista siihen kontekstiin, johon teksti menee.
Pikavastaukset

“Onko plusmerkki URL-osoitteessa välilyönti?”

Vain lomakedatassa, ja vain lomakelähetyksen kyselyosassa. Polussa, fragmentissa ja tavallisen linkin kyselyssä plusmerkki on kirjaimellinen plusmerkki. Siksi tällä sivulla on kytkin siihen sen sijaan, että se arvattaisiin.

“Miksi linkkini näyttää %25?”

Koska jokin on koodannut prosenttimerkin. Joko kirjaimellinen prosenttimerkki meni koodaimen läpi — 100% sure muuttuu muotoon 100%25%20sure — tai jo escapeja sisältävä merkkijono koodattiin toisen kerran. Pura merkkijono kerran ja katso, mitä tulee takaisin: jos tulos sisältää yhä %XX-muotoja, on vielä yksi kerros.

“Onko sillä merkitystä, onko kyselyarvon sisällä oleva kauttaviiva %2F vai /?”

URL-jäsentimelle ei: molemmat saapuvat palvelimelle kauttaviivana, ja WHATWG:n kyselyjoukko jättää kauttaviivan rauhaan. Yhteentoimivuudelle joskus: monet palvelinkehykset tekevät omaa purkua raakaan kyselymerkkijonoon, ja muutamat ovat eri mieltä merkeistä, joita ei koskaan escapeoitu. Kun arvo kootaan käsin eikä sarjoittajalla, varattujen merkkien eksplisiittinen escapeaminen on turvallisempi tapa.

“Miksi lomakesarake escapeaa tildin, jonka kaksi muuta jättävät rauhaan?”

Koska lomakekoodaajan turvallinen joukko on kapeampi: siinä ovat vain kirjaimet, numerot ja -_.*. WHATWG:n lomakekoodaaja escapeaa merkit ~ ! ' ( ), vaikka RFC 3986 luettelee ~-merkin varaamattomana. Molemmat kirjoitusasut purkautuvat samaksi arvoksi; ero merkitsee vain silloin, kun merkkijonoja verrataan tavu tavulta.

“Voivatko samat merkit esiintyä escapeamattomina selaimen osoitepalkissa?”

Kyllä, ja se on osoitepalkki, ei URL-osoite. Selaimet näyttävät URL-osoitteen luettavassa muodossa ja koodaavat sen lähettäessään, joten 中文 linkissä muuttuu langalla muotoon %E4%B8%AD%E6%96%87. Jos kopioit URL-osoitteen osoitepalkista, saadaan riippuen selaimesta jommankumman muodon.

“Jokainen escape täällä näyttää kelvolliselta, mutta ulos tuleva merkki ei ole se, jonka odotin. Miksi?”

Kahden eri virheen takana on "purkaminen meni väärin", ja tämä sivu raportoi ne eri tavalla. Ensimmäinen on rikkinäinen escape: prosenttimerkki, jota ei seuraa kaksi heksanumeroa, kuten loppuun jäävä 100% tai %zz. Se on syntaksiongelma: tiukka lukutapa hylkää sen ja kertoo sijainnin, kun löysä lukutapa säilyttää sen kirjaimellisena tekstinä ja luettelee sen. Toinen on escape, jonka tavu on täysin laillinen, mutta tavut eivät muodosta kelvollista UTF-8-merkkiä, kuten yksittäinen %FF tai kolmitavuinen merkki katkaistuna muotoon %E4%B8. Se ei ole syntaksiongelma, joten molemmat lukutavat palauttavat tekstin, korvaavat purkamattomat tavut korvausmerkillä U+FFFD ("�") ja luettelevat varoituksen, joka kertoo sen. Varoitus on hyödyllinen osa: teksti, joka saapuu korvausmerkkeinä, tarkoittaa yleensä, että lähettäjä käytti eri merkistöä tai että merkkijono escapeoitiin yhden kerran liian monta. Prosenttikoodaus nimeää tavuja, ja tämä sivu lukee nuo tavut aina UTF-8:na, kuten URL-standardi.

“Mitä tämä sivu ei tee?”

Se ei jaa URL-osoitetta skeemaan, isäntään, polkuun ja kyselyyn — siihen on URL-jäsennin. Se ei tarkista, onko linkki turvallinen avata, ei ota yhteyttä mihinkään, eikä arvaa escapen takana olevien tavujen merkistöä: se lukee ne aina UTF-8:na, kuten URL-standardi vaatii.

“Mitä varasarjaa purku tarvitsee, ja mistä tiedän, että se on oikein?”

Paina Itsetesti. Se vertaa sivun omia koodaimia alustan encodeURIComponent-, encodeURI- ja URLSearchParams-funktioihin jokaisen tulostettavan ASCII-merkin kohdalla, ajaa uudelleen kaikki yllä olevien taulukoiden esimerkit, tarkistaa kirjatut kerrosketjut ja raportoi tarkistusten määrän tässä.

Standardit ja laajuus

Prosenttikoodaus on määritelty RFC 3986 -kohdassa 2.1, varattujen ja varaamattomien merkkien määritelmä on kohdissa 2.2 ja 2.3 ja kirjainkokosääntö kohdassa 6.2.2.1. Joukot, joita selain todella käyttää URL-osoitteen rakentamisessa, ovat WHATWG URL -standardissa, joka jakaa ne kontekstin mukaan: yksi fragmentille, yksi kyselylle, yksi erikoiskyselylle, yksi polulle, yksi käyttäjätiedoille ja kapeampi yhden osan koodaukseen. Lomakelähetys, plusmerkki mukaan lukien, on HTML-standardissa kohdassa application/x-www-form-urlencoded. Funktiot encodeURI ja encodeURIComponent ovat osa ECMAScriptiä itseään.

Tämä sivu täyttää polku-, kysely- ja fragmenttisarakkeet omista kontekstikohtaisista joukoistaan ja tulostaa jokaiselle kontekstille tarkan luettelon tuloksen viereen. Nuo joukot on johdettu WHATWG:n joukoista ja eroavat niistä kahdessa tarkoituksellisessa kohdassa: risuaita escapeaan kyselyn sisällä, koska raaka risuaita aloittaisi fragmentin, ja komponenttijoukko on lukittu täsmälleen niihin merkkeihin, joita encodeURIComponent escapeaa. Kohdissa, joissa alustan funktio on vastauksen määritelmä — encodeURIComponent, encodeURI ja lomakesarjoitus — kyseinen funktio kutsutaan suoraan, joten ne sarakkeet ovat selaimen omaa toimintaa eivätkä sen uudelleentoteutusta.

Teksti sivulla on kirjoitettu tälle sivustolle. Jokainen yllä olevien taulukoiden arvo tuotetaan sivun omalla koodilla latausaikana, ja se on tarkistettu alustan toteutuksia vastaan tämän sivuston testityökaluissa; Itsetesti toistaa vertailun selaimessa.