Por que nos endereços aparecem %20 e %C3%A7

Uma URL só pode conter um pequeno conjunto de caracteres: letras, dígitos e poucos símbolos. Todo o resto, espaços, letras acentuadas, o ç, emoji, é primeiro convertido em bytes UTF-8 e depois cada byte é escrito como % seguido de dois dígitos hexadecimais. O espaço vira %20, o ç vira %C3%A7.

Alguns caracteres têm significado estrutural: / separa os trechos do caminho, ? abre a query string, & separa os parâmetros, = separa nome e valor, # introduz o fragmento. Dentro de um valor precisam ser codificados, senão quebram o endereço. Essa é a diferença entre encodeURIComponent, que os codifica, e encodeURI, que os mantém porque trabalha sobre uma URL inteira.

Em formulários web e query strings o espaço também é escrito muitas vezes como +. Por isso a decodificação aqui transforma o + em espaço, como fazem os servidores; num caminho, porém, o + continua sendo um +.

Erros comuns

  • Usar encodeURI para o valor de um parâmetro: um & no valor divide o parâmetro em dois.
  • Codificar duas vezes: %20 vira %2520 e o servidor recebe o texto literal %20.
  • Montar uma URL concatenando strings não codificadas: além de erros, abre caminho para injeção de parâmetros.

Perguntas frequentes

Qual a diferença entre encodeURI e encodeURIComponent?

encodeURIComponent codifica tudo, menos letras, dígitos e - _ . ! ~ * ' ( ): serve para um único valor. encodeURI mantém também : / ? # [ ] @ & = + $ , ;: serve para um endereço já montado.

Por que o espaço às vezes é %20 e às vezes +?

%20 é a codificação geral do espaço numa URL. O + vem dos formulários HTML (application/x-www-form-urlencoded) e só vale como espaço na query string.

O que é Punycode?

É o jeito como domínios com caracteres não ASCII, como açaí.com.br, são escritos no DNS: xn--aa-4iaz.com.br. O navegador mostra a forma legível, mas usa a codificada por baixo.

Como funciona este cálculo

Codificação: o texto é convertido em bytes UTF-8 e cada byte fora do conjunto permitido vira %HH, sendo HH o seu valor hexadecimal. encodeURIComponent só permite A–Z a–z 0–9 - _ . ! ~ * ' ( ); encodeURI permite também ; , / ? : @ & = + $ #. Decodificação: cada %HH volta ao seu byte, os bytes são lidos como UTF-8 e o + vira espaço.