Ogni URL che hai mai digitato o cliccato è passato dalla codifica URL. Lo spazio in “mio file.txt” diventa %20. Il & in una stringa di query diventa %26. Il / in un percorso resta / — ma solo perché il codificatore sa quali caratteri sono sicuri e quali no.
La codifica URL (ufficialmente “codifica percentuale”) è il modo in cui gli URL rappresentano caratteri che non fanno parte dell’insieme di caratteri non riservati. È una trasformazione semplice, ma i casi limite sono dove vivono la maggior parte dei bug delle API.
I caratteri non riservati
Questi caratteri sono sempre sicuri negli URL e non necessitano mai di codifica:
A-Z a-z 0-9 - _ . ~
Tutto il resto — spazi, barre, e commercial, segni di uguaglianza, caratteri non ASCII — deve essere codificato come un segno di percentuale seguito da due cifre esadecimali:
- Spazio →
%20 &→%26=→%3D/→%2F?→%3F#→%23
La codifica sono i valori byte UTF-8 del carattere, ciascuno rappresentato da due cifre esadecimali. Un carattere multi-byte come é (UTF-8: 0xC3 0xA9) diventa %C3%A9.
Dove la codifica conta
Parametri di query. Questo è dove la codifica URL causa la maggior parte dei bug. Se un valore di query contiene & o =, l’analizzatore URL si divide su quei caratteri e rompe la struttura del parametro:
/search?q=cats&dogs ← ambiguo: "dogs" è un parametro separato?
/search?q=cats%26dogs ← corretto: "cats&dogs" è un singolo valore
Ogni libreria HTTP ha una funzione per codificare i parametri di query. Usala. Non concatenare mai manualmente stringhe in una stringa di query.
Percorsi. Gli spazi nei nomi file necessitano di codifica:
/download/my file.pdf ← rotto
/download/my%20file.pdf ← funziona
Ma le barre all’interno di un segmento di percorso necessitano anche di codifica:
/file/path/segment ← due segmenti: "file/path" diviso da /
/file%2Fpath/segment ← un segmento: "file/path"
Caratteri non ASCII. Gli URL sono solo ASCII. Qualsiasi carattere non ASCII (lettere accentate, caratteri CJK, emoji) deve essere codificato con percentuale:
café→caf%C3%A9日本語→%E6%97%A5%E6%9C%AC%E8%AA%9E🎉→%F0%9F%8E%89
La maggior parte dei browser mostra la versione decodificata nella barra degli indirizzi, ma i byte effettivi inviati sulla rete sono codificati.
La trappola della doppia codifica
Il bug di codifica URL più comune: codificare una stringa già codificata.
Prendi il percorso /hello%20world. Se lo codifichi di nuovo in URL, il % diventa %25:
/hello%20world ← originale (corretto)
/hello%2520world ← doppio codificato (rotto)
Il server decodifica %25 in %, poi vede %20 e lo decodifica in uno spazio. Finisci con /hello world — ma solo se il server fa una singola decodifica. Se ne fa due (alcuni lo fai), ottieni l’originale. Il comportamento è incoerente e imprevedibile.
La regola: codifica una volta, decodifica una volta. Se ricevi una stringa codificata, decodificala prima di ricodificare. Controlla se il costruttore URL della tua libreria HTTP si aspetta valori raw o pre-codificati — la differenza tra path e rawPath nella maggior parte dei framework conta.
Codifica stringa di query
Le stringhe di query hanno le proprie regole di codifica. La differenza chiave dai percorsi: + rappresenta uno spazio nelle stringhe di query (application/x-www-form-urlencoded), ma %20 rappresenta anche uno spazio. Entrambi sono validi, ma vengono da standard diversi:
application/x-www-form-urlencoded(invii di modulo) —+per gli spazi- Codifica percentuale (URL) —
%20per gli spazi
La maggior parte delle API moderne accetta entrambi. Ma se stai analizzando una stringa di query da un invio di modulo, + → spazio. Se stai costruendo un URL, %20 → spazio. Mescolarli causa bug sottili dove gli spazi diventano segni + o viceversa.
Usa la funzione di codifica URL del tuo linguaggio. Si occupa della distinzione per te.
Codifica vs escape
La codifica URL non è l’escape HTML. Risolvono problemi diversi:
- Codifica URL (
%20) — per caratteri negli URL. Impedisce che i caratteri vengano interpretati come sintassi URL. - Escape HTML (
&,<) — per caratteri in HTML. Impedisce che i caratteri vengano interpretati come tag o entità HTML.
Un URL in un href HTML richiede entrambi: codifica i valori dei parametri in URL, poi codifica l’intero URL in HTML:
<a href="/search?q=cats%26d&page=1">
Il %26 impedisce che & venga interpretato come separatore di query. Il & impedisce che & venga interpretato come inizio di entità HTML.
Insidie comuni
Spazi in contesti diversi. %20 in un URL, + in un corpo di modulo, %2520 se hai accidentalmente codificato due volte. Sii consapevole del contesto in cui ti trovi.
** frammenti hash.** Tutto dopo # non viene inviato al server. Se codifichi un URL con un frammento e il frammento contiene ? o &, il server non li vede mai. Il frammento è solo lato client.
Codificare il segno di percentuale. % → %25. Se un % letterale appare nei tuoi dati (come una password con %), deve essere codificato. Se non lo codifichi, l’analizzatore interpreta i due caratteri dopo di esso come una sequenza esadecimale.
Normalizzazione Unicode. Alcuni sistemi normalizzano Unicode prima della codifica. café (con accento combinante) e café (con é precomposto) codificano in diverse sequenze percentuali. Questo causa problemi con i nomi file e i nomi di dominio internazionalizzati.
Riferimento rapido | Carattere | Codificato con percentuale | Contesto | |———–|—————————|–––––| | Spazio | %20 | URL | | Spazio | + | Corpo di modulo | | & | %26 | Stringa di query | | = | %3D | Stringa di query | | / | %2F | Segmento di percorso | | ? | %3F | Stringa di query | | # | %23 | Percorso/query | | % | %25 | Ovunque | | + | %2B | Stringa di query |
Prova
Se hai un URL o una stringa codificata da decodificare (o dati raw da codificare), usa uno strumento locale affinché la conversione avvenga nel tuo browser — nessun dato viene inviato da nessuna parte.