Todo caractere de um endereço web precisa vir de um conjunto pequeno e seguro com o qual navegadores, servidores, proxies e logs concordem. Quando você precisa colocar em um link algo fora desse conjunto - um espaço, um e comercial, uma letra acentuada ou um emoji - é preciso fazer a codificação de URL antes. A codificação de URL, também chamada de percent-encoding, é o padrão que substitui esses caracteres por um sinal de porcentagem seguido do valor do byte em hexadecimal, de modo que um espaço vira %20 e & vira %26. Este guia explica o que é a codificação de URL, quais caracteres precisam dela, como funciona o formato %XX e a escolha entre encodeURIComponent e encodeURI que confunde a maioria dos desenvolvedores - com exemplos práticos que você pode copiar.
Resposta rápida
A codificação de URL (percent-encoding) substitui caracteres inseguros ou reservados em uma URL por um % seguido de dois dígitos hexadecimais que representam o byte do caractere em UTF-8. Um espaço vira %20, um e comercial vira %26 e um e acentuado (é) vira %C3%A9. Use encodeURIComponent para valores individuais que você insere em uma URL e encodeURI para uma URL completa que você não quer quebrar.
O que é codificação de URL?
A codificação de URL é uma forma de representar caracteres em um Uniform Resource Locator (URL) usando apenas um conjunto limitado e universalmente seguro de caracteres. O padrão de URL (RFC 3986) permite que só um punhado de caracteres apareça de forma literal: as letras ASCII A-Z e a-z, os dígitos 0-9 e alguns poucos símbolos. Todo o resto - espaços, a maior parte da pontuação e qualquer caractere fora do inglês - precisa ser convertido em uma sequência percent-encoded antes de viajar com segurança dentro de um link.
O motivo é que as URLs passam por muitos sistemas, e alguns caracteres têm significado especial para esses sistemas. Um espaço pode ser descartado silenciosamente ou virar um +, um # inicia o fragmento e um ? inicia a query string. O percent-encoding elimina a ambiguidade transformando qualquer caractere problemático em um código que significa "isto é dado, não um delimitador".
Caracteres reservados vs não reservados
A especificação de URL divide os caracteres em grupos. Saber quem é quem diz exatamente o que precisa ser codificado e o que deve ficar como está.
Caracteres não reservados (nunca codificados)
Estes caracteres são sempre seguros de usar como estão em qualquer parte de uma URL e não devem ser codificados:
- Letras maiúsculas: A-Z
- Letras minúsculas: a-z
- Dígitos: 0-9
- Quatro símbolos: hífen (-), underscore (_), ponto (.) e til (~)
Caracteres reservados (codifique quando forem usados como dado)
Os caracteres reservados têm uma função especial na URL - eles atuam como delimitadores que separam uma parte da outra. Só são seguros quando estão cumprindo essa função. Se um caractere reservado aparece dentro de um valor em vez de atuar como separador, ele precisa ser codificado para não ser confundido com um delimitador.
- Delimitadores de path e authority: / : @
- Delimitadores de query e fragment: ? # & =
- Sub-delimitadores: ! $ & ' ( ) * + , ; =
Por exemplo, o & em https://example.com/search?q=cats&sort=new separa dois parâmetros de query, então ele fica literal. Mas se você busca pela frase "cats & dogs", o & dentro desse valor precisa virar %26 - caso contrário o servidor lê &dogs como um segundo parâmetro.
O formato %XX explicado
O percent-encoding segue uma regra simples: um sinal de porcentagem (%) seguido de dois dígitos hexadecimais. Esses dois dígitos são o valor de um único byte escrito em base 16 (00 a FF, ou seja, 0-255 em decimal). Para codificar um caractere, você consulta o valor do byte dele e escreve esse valor depois do %.
- O espaço é 32 em decimal, que é 20 em hexadecimal - então um espaço vira %20.
- O e comercial & é 38 em decimal = 26 em hex - então & vira %26.
- O sinal de igual = é 61 em decimal = 3D em hex - então = vira %3D.
- O ponto de interrogação ? é 63 em decimal = 3F em hex - então ? vira %3F.
Caracteres na faixa ASCII (0-127) ocupam um único byte, então sempre são codificados em uma sequência %XX. Caracteres fora do ASCII são convertidos primeiro para os seus bytes UTF-8 - que podem ser dois, três ou quatro bytes - e cada byte vira o seu próprio %XX. É por isso que a letra acentuada é (U+00E9) é codificada como %C3%A9: a forma UTF-8 dela são os dois bytes C3 e A9.
encodeURIComponent vs encodeURI - quando usar cada um
O JavaScript oferece duas funções nativas para percent-encoding, e escolher a errada é o erro mais comum de codificação de URL. A diferença está em quais caracteres reservados cada uma deixa intactos.
encodeURIComponent - para um único valor
encodeURIComponent codifica quase tudo que não é um caractere não reservado, incluindo os delimitadores reservados / ? : @ & = + $ #. Use essa função para um único pedaço de dado que você insere na URL - um valor de parâmetro de query, um segmento de path ou um campo de formulário. Como ela escapa & e =, um valor que contenha esses caracteres não vai quebrar a query string ao redor.
encodeURI - para uma URL inteira
encodeURI foi feita para codificar uma URL completa e já montada. Ela deixa os delimitadores reservados intactos - :, /, ?, #, & e = passam sem alteração - para que a URL mantenha a sua estrutura. Ela só codifica caracteres que nunca são válidos em lugar nenhum, como espaços. Use essa função quando você tem uma URL completa que pode conter um caractere ilegal e não quer alterar as partes dela.
Regra prática
Codifique as partes, não o todo. Monte a URL rodando encodeURIComponent em cada valor individual primeiro e depois juntando tudo você mesmo com os delimitadores &, =, / e ?. Recorra ao encodeURI só quando alguém te entregar uma string de URL completa para limpar.
Duas observações práticas: encodeURIComponent não escapa os caracteres ! ' ( ) *, então um parser rigoroso pode exigir que você os substitua na mão. E nunca codifique uma string que já está codificada - fazer isso transforma cada % em %25, então %20 vira %2520, um bug clássico de dupla codificação que produz links quebrados.
Exemplos práticos
Veja como caracteres comuns ficam antes e depois da codificação. Cada linha se lê como caractere - o que ele é - forma codificada.
- Espaço - separador de palavras - %20 (o + também é usado para espaços em query strings; veja abaixo)
- & - e comercial - %26
- = - sinal de igual - %3D
- ? - ponto de interrogação - %3F
- / - barra - %2F
- # - hash / início do fragmento - %23
- + - sinal de mais - %2B
- é - e com acento agudo (não ASCII, 2 bytes UTF-8) - %C3%A9
- 😀 - emoji (4 bytes UTF-8) - %F0%9F%98%80
Codificando um valor com espaços e símbolos
Digamos que você queira passar a frase de busca "cats & dogs = fun" como um único valor de query. Rodar encodeURIComponent nela produz cats%20%26%20dogs%20%3D%20fun. Cada espaço, o & e o = são escapados, então tudo é tratado como um valor só, e não como três parâmetros separados.
Um exemplo completo de query string
Juntando tudo, imagine uma página de busca que recebe um termo e uma categoria. Você codifica cada valor separadamente e depois monta a URL:
- Valor bruto da query: cats & dogs
- Valor bruto da categoria: pets/animals
- Query codificada: cats%20%26%20dogs
- Categoria codificada: pets%2Fanimals
- URL final: https://example.com/search?q=cats%20%26%20dogs&category=pets%2Fanimals
Repare que o & e o = entre q=... e category=... ficam literais porque estão cumprindo o papel de delimitadores, enquanto o & dentro do valor da query e a / dentro do valor da categoria são codificados porque são dados. É exatamente isso que você obtém ao codificar cada valor com encodeURIComponent e depois juntar as peças você mesmo.
Espaço: %20 ou +?
No path de uma URL, um espaço é sempre %20. Em uma query string, a codificação de formulários mais antiga (application/x-www-form-urlencoded) usa + no lugar do espaço. As duas decodificam de volta para um espaço, mas não são intercambiáveis em todo lugar - ao decodificar, verifique se a origem usou %20 ou + para restaurar o texto original corretamente.
Perguntas frequentes
O que é codificação de URL em termos simples?
A codificação de URL é uma forma de incluir com segurança caracteres especiais em um endereço web, substituindo-os por um % e um código de dois dígitos. Como as URLs só podem conter um conjunto limitado de caracteres, qualquer outra coisa - como um espaço, um e comercial ou uma letra acentuada - é convertida no equivalente percent-encoded (um espaço vira %20) para que o link continue válido.
Por que as URLs têm %20?
%20 é a forma percent-encoded de um espaço. Espaços não são permitidos em uma URL, então quando um link contém um - muitas vezes vindo de um nome de arquivo ou de um termo de busca - ele é substituído por %20. Quando a página carrega, o servidor ou o navegador decodifica %20 de volta para um espaço.
Qual é a diferença entre encodeURI e encodeURIComponent?
encodeURIComponent codifica um único valor e escapa os delimitadores reservados (& = ? / #), o que a torna certa para um parâmetro de query ou um segmento de path. encodeURI codifica uma URL inteira e deixa esses delimitadores intactos para que o endereço mantenha a sua estrutura. Use encodeURIComponent para as partes e encodeURI para uma URL completa.
Quais caracteres precisam ser codificados na URL?
Só os caracteres não reservados - A-Z, a-z, 0-9 e - _ . ~ - são sempre seguros. Todo o resto deve ser codificado quando aparece dentro de um valor: espaços, a maior parte da pontuação, os delimitadores reservados (/ ? : @ & = + $ , ; # ! ' ( ) *) e todos os caracteres não ASCII, como letras acentuadas e emoji.
Codificação de URL é a mesma coisa que criptografia ou Base64?
Não. A codificação de URL não é criptografia e não oferece segurança nenhuma - é uma transformação de texto totalmente reversível que apenas deixa os caracteres seguros para viajar em uma URL, e qualquer pessoa consegue decodificá-la na hora. Ela também é diferente de Base64, que recodifica dados binários em um alfabeto de 64 caracteres com outro propósito.
Como decodifico uma string codificada em URL?
Inverta o processo: cada sequência %XX é convertida de volta no byte que representa, e os bytes consecutivos são lidos como UTF-8 para recuperar caracteres como é ou emojis. Em JavaScript, decodeURIComponent faz isso; uma ferramenta de decodificação de URL faz o mesmo no seu navegador e mostra um erro claro se a entrada tiver uma sequência malformada, como um % solto.
Codifique ou decodifique uma URL na hora
Use o Codificador / Decodificador de URL gratuito para fazer percent-encoding de qualquer texto ou decodificar uma URL codificada - alterne entre encodeURIComponent e encodeURI com um clique, e tudo roda no seu navegador.