Codificatore / decodificatore URL
Codifica e decodifica URL, scegli l’ambito componente o URL completo, e scomponi un URL nelle sue parti.
Per un singolo valore, come un parametro di query. Protegge anche / ? : @ & = + perché lì sono dati e non struttura.
L’output apparirà qui
A cosa serve la codifica percentuale
Un URL può contenere solo un piccolo insieme di caratteri: le lettere A–Z e a–z, le cifre, una manciata di segni come - . _ ~, e un insieme di caratteri riservati che gli danno forma — / ? # & = : @ e pochi altri. Tutto il resto, da uno spazio a una parola in ebraico a un’emoji, va rappresentato indirettamente. La codifica percentuale è quella rappresentazione: il carattere viene convertito nei suoi byte UTF-8 e ogni byte è scritto come un segno di percentuale seguito da due cifre esadecimali. Uno spazio diventa %20, e א diventa %D7%90.
I caratteri riservati sono il caso interessante. Sono leciti in un URL, ma hanno un significato strutturale: ? apre la query, & separa i parametri, = divide una chiave dal suo valore. Quando uno di questi caratteri fa parte dei tuoi dati anziché della struttura, va codificato — altrimenti il parser dall’altra parte lo leggerà come punteggiatura e spezzerà il tuo valore nel punto sbagliato.
Componente o URL completo: la distinzione che rompe i link
È la fonte più comune di bug sugli URL, ed è per questo che lo strumento ti chiede di scegliere un ambito invece di indovinare.
- L’ambito componente protegge anche i delimitatori: / ? : @ & = + $ , e #. Usalo per un singolo dato — un termine di ricerca, una destinazione di reindirizzamento, un token — che verrà inserito dentro un URL più grande.
- L’ambito URL completo lascia intatti quei delimitatori e protegge solo ciò che è davvero illecito, come gli spazi e il testo non ASCII. Usalo quando hai un indirizzo completo già strutturato correttamente che va soltanto ripulito.
Sbagliare in una direzione o nell’altra rompe qualcosa. Codifica un URL intero in ambito componente e ogni barra e punto interrogativo diventano %2F e %3F, producendo un’unica stringa inutilizzabile. Codifica un singolo valore in ambito URL completo e una e commerciale al suo interno sopravvive come delimitatore: una ricerca di «gatti & cani» diventa silenziosamente due parametri e la seconda metà del tuo valore sparisce.
// Il valore contiene un delimitatore, quindi va protetto:
const q = 'cats & dogs'
`/search?q=${encodeURIComponent(q)}` // /search?q=cats%20%26%20dogs
`/search?q=${encodeURI(q)}` // /search?q=cats%20&%20dogs ✗
// Meglio ancora: lascia che sia la piattaforma a comporlo
const url = new URL('https://example.com/search')
url.searchParams.set('q', 'cats & dogs')Vale la pena adottare quest’ultimo approccio come abitudine. URL e URLSearchParams sono integrati in ogni browser e in Node, e applicano la codifica corretta a ciascuna parte al posto tuo — il che elimina la decisione invece di costringerti a indovinare giusto a mano ogni volta.
Perché uno spazio a volte è + e a volte %20
Qui agiscono due specifiche diverse, e divergono su esattamente un carattere. L’RFC 3986, che regola gli URL in generale, codifica uno spazio come %20. Il più vecchio formato application/x-www-form-urlencoded, quello che inviano i moduli HTML e a cui perciò assomigliano quasi tutte le query string, lo codifica come +.
La trappola è che decodeURIComponent implementa solo la prima regola. Dagli hello+world e riavrai hello+world, più compreso — nessun errore, nessun avviso, solo un valore sottilmente sbagliato. Per questo lo strumento offre l’opzione «tratta + come spazio» e te la segnala quando il tuo input contiene un più mentre l’opzione è disattivata.
Nota che URLSearchParams, che alimenta la tabella di scomposizione sotto lo strumento, segue le regole dei moduli e converte eccome + in spazio. La stessa query string può quindi decodificarsi diversamente a seconda dell’API che usi — deliberatamente, e correttamente, in entrambi i casi.
Una conseguenza da ricordare: se un più fa davvero parte dei tuoi dati — un numero di telefono, un’espressione di filtro — va codificato come %2B. Un + letterale in una query string è ambiguo nel migliore dei casi e sarà letto come spazio dalla maggior parte dei parser.
Leggere un URL
Incolla un URL assoluto e lo strumento lo divide nelle sue parti. Vale la pena sapere come si chiama ciascuna, perché i messaggi di errore e la documentazione danno per scontato il lessico:
- Schema — https, mailto, ftp. Tutto ciò che precede i due punti, e ciò che decide come interpretare il resto.
- Info utente — un user:password facoltativo prima dell’host. Ancora lecito, e ancora una cattiva idea: viaggia con ogni richiesta e finisce nei log, nella cronologia del browser e nelle intestazioni referrer.
- Host — il nome di dominio o l’indirizzo IP. Tutto ciò che segue è gestito da quel server, non dalla rete.
- Porta — di solito assente, perché 443 per https e 80 per http sono sottintese.
- Origine — schema, host e porta insieme. È l’unità su cui è costruita la sicurezza del browser: la stessa origine, il CORS e l’ambito dei cookie confrontano origini, non percorsi.
- Percorso — la parte dopo l’host e prima di qualsiasi ? o #.
- Query — le coppie chiave/valore dopo il ?, separate da &.
- Frammento — tutto ciò che segue il #. Unico nel suo genere, non viene mai inviato al server: lo gestisce interamente il browser.
Il dettaglio sul frammento conta più di quanto sembri. Poiché non lascia mai il browser, tutto ciò che metti dopo un # è invisibile ai log del server — motivo per cui alcune applicazioni a pagina singola lo usavano storicamente per il routing, e per cui non è lì che bisogna guardare quando si indaga su una richiesta mai arrivata.
Un ultimo avvertimento su ciò che la codifica non fa. La codifica percentuale rende il testo trasportabile in sicurezza dentro un URL; non è sanificazione né un controllo di sicurezza. Codificare un valore non lo rende sicuro da interpolare in HTML, SQL o un comando di shell, e decodificare input non fidato può rivelare caratteri — separatori di percorso, byte nulli — che la forma codificata nascondeva. Valida che cosa sia un valore, separatamente dalla codifica di come viaggia.
L’indirizzo che digiti non è sempre quello che parte
Prima che un URL vada da qualche parte viene normalizzato, e la riscrittura è silenziosa. Questo strumento mostra il risultato ogni volta che differisce dall’input, perché è quella stringa — non quella digitata — ad arrivare al server e a comparire in un log:
HTTPS://Example.COM:443\a\b digitato https://example.com/a/b inviato
Lì sono scattate quattro regole distinte. Schema e host passano in minuscolo, dato che nessuno dei due distingue le maiuscole. La porta sparisce perché 443 è quella predefinita per https. Le barre rovesciate diventano barre normali, una regola di compatibilità che sorprende chi scrive percorsi in stile Windows. E un percorso vuoto sarebbe diventato una singola barra. Nulla di questo è un errore, ma se confronti due URL, o ne verifichi uno contro una lista di consentiti, devi confrontare le forme normalizzate o otterrai la risposta sbagliata.
Anche un nome host con caratteri non ASCII viene riscritto, in una forma ASCII che comincia per xn--, chiamata punycode. Lo strumento mostra entrambe le direzioni: il nome leggibile e quello che viaggia davvero. Vale la pena guardarlo invece di saltarlo, perché due nomi Unicode diversi possono apparire identici sullo schermo — una «a» latina e una «а» cirillica sono caratteri distinti — pur producendo un punycode completamente diverso. Confrontare le forme ASCII è l’unico modo affidabile per distinguere una coppia simile.
Una cosa non viene mai normalizzata: un parametro di query ripetuto. Scrivere ?tag=a&tag=b è del tutto lecito, e lo standard non dice che cosa significhi, così ogni stack ha scelto la propria risposta. PHP tiene l’ultimo valore, Express li raccoglie in un array, e molti framework insieme a URLSearchParams.get prendono il primo. Lo strumento segnala le chiavi ripetute anziché elencarle due volte senza commento, perché il bug che ne deriva — un valore che funziona in un servizio e sparisce in un altro — è davvero difficile da notare leggendo.
Domande frequenti
- Qual è la differenza tra ambito componente e URL completo?
- L’ambito componente protegge anche i delimitatori / ? : @ & = +, il che è giusto per un singolo valore inserito dentro un URL. L’ambito URL completo li lascia intatti perché lì separano le parti dell’indirizzo. Usare l’ambito componente su un URL intero trasforma ogni barra in %2F e produce una stringa inutilizzabile.
- Perché il mio testo decodificato contiene ancora un +?
- Perché decodeURIComponent segue l’RFC 3986, dove + è solo un più. L’invio dei moduli e quasi tutte le query string usano la codifica dei moduli, dove + significa spazio. Attiva «tratta + come spazio» quando il testo proviene da uno dei due.
- Come codifico un più che è davvero un più?
- Scrivilo come %2B. Un + letterale in una query string sarà letto come spazio dalla maggior parte dei parser, quindi ogni più che faccia davvero parte dei tuoi dati — in un numero di telefono, per esempio — va protetto.
- Devo codificare l’intero URL o solo le parti?
- Solo le parti, e preferibilmente non a mano: costruisci l’indirizzo con URL e URLSearchParams, che applicano la codifica corretta a ciascun componente. Codificare a posteriori un URL già assemblato è l’origine della maggior parte dei bug di doppia codifica.
- Perché la scomposizione mostra un URL diverso da quello che ho incollato?
- Perché è quello che parte. Un URL viene normalizzato prima dell’uso: schema e host passano in minuscolo, una porta predefinita sparisce, le barre rovesciate diventano barre, un percorso vuoto diventa una barra, e un host non ASCII diventa punycode. Se confronti URL o li verifichi contro una lista di consentiti, confronta queste forme normalizzate e non il testo grezzo.
- Perché non compare la scomposizione per example.com/path?
- Perché non è un URL assoluto: non ha schema, quindi non c’è alcun host da identificare. Lo strumento non ne indovina uno al posto tuo: example.com:8080 è già un URL assoluto valido il cui schema è example.com e il cui percorso è 8080, perciò anteporre https:// in silenzio può produrre una scomposizione che sembra ragionevole ed è sbagliata. Aggiungi tu lo schema e le parti compariranno.
- Che cos’è la doppia codifica?
- Codificare un valore già codificato, così che un %20 diventi %2520 — viene protetto il segno di percentuale stesso. Di solito si manifesta come sequenze %20 letterali che compaiono in una pagina. Decodifica una volta e verifica se vedi ancora sequenze di escape; se sì, era stato codificato due volte.
- Codificare un valore lo rende sicuro?
- No. La codifica percentuale riguarda il trasporto, non la sicurezza. Un valore codificato è ancora quello che era, e ha bisogno della stessa validazione e dello stesso escaping adatto al contesto prima di raggiungere HTML, SQL o una shell.
- Perché il frammento non viene inviato al server?
- Per progetto: tutto ciò che segue il # è gestito solo dal browser e non compare mai nella richiesta. È per questo che non si vede nei log del server, ed è per questo che storicamente è stato usato per il routing lato client.
- Quello che incollo viene inviato da qualche parte?
- No. Codifica, decodifica e scomposizione dell’URL usano le funzioni integrate del browser e vengono eseguite interamente sul tuo dispositivo. Nulla di ciò che incolli lo lascia.