Perché negli indirizzi compaiono %20 e %C3%A8

Un URL può contenere solo un piccolo insieme di caratteri: lettere, cifre e pochi simboli. Tutto il resto, spazi, lettere accentate, emoji, viene prima trasformato in byte UTF-8 e poi ogni byte scritto come % seguito da due cifre esadecimali. Lo spazio diventa %20, la è diventa %C3%A8.

Alcuni caratteri hanno un significato strutturale: / separa i tratti del percorso, ? apre la query string, & separa i parametri, = separa nome e valore, # introduce il frammento. Se compaiono dentro un valore, vanno codificati, altrimenti spezzano l'indirizzo. È la differenza fra encodeURIComponent, che li codifica, ed encodeURI, che li lascia perché lavora su un URL intero.

Nei moduli web e nelle query string lo spazio si scrive spesso anche come +. Per questo la decodifica qui trasforma il + in spazio, come fanno i server; in un percorso, invece, il + resta un +.

Errori frequenti

  • Usare encodeURI per un valore di un parametro: un & nel valore divide il parametro in due.
  • Codificare due volte: %20 diventa %2520 e il server riceve il testo letterale %20.
  • Costruire un URL concatenando stringhe non codificate: oltre agli errori, è una porta aperta all'iniezione di parametri.

Domande frequenti

Che differenza c'è fra encodeURI ed encodeURIComponent?

encodeURIComponent codifica tutto tranne lettere, cifre e - _ . ! ~ * ' ( ): serve per un singolo valore. encodeURI lascia anche : / ? # [ ] @ & = + $ , ;: serve per un indirizzo già composto.

Perché lo spazio a volte è %20 e a volte +?

%20 è la codifica generale dello spazio in un URL. Il + viene dai moduli HTML (application/x-www-form-urlencoded) e vale come spazio solo nella query string.

Che cos'è il Punycode?

È il modo in cui i domini con caratteri non ASCII, come città.it, vengono scritti nel DNS: xn--citt-3na.it. Il browser mostra la forma leggibile, ma sotto usa quella codificata.

Come funziona questo calcolo

Codifica: il testo viene convertito in byte UTF-8 e ogni byte fuori dall'insieme ammesso diventa %HH, con HH il valore esadecimale del byte. encodeURIComponent ammette solo A–Z a–z 0–9 - _ . ! ~ * ' ( ); encodeURI ammette anche ; , / ? : @ & = + $ #. Decodifica: ogni %HH torna al suo byte, la sequenza di byte viene letta come UTF-8 e il + diventa spazio.