Codificador e Decodificador de URL

Componente também escapa / ? & = — use para um único valor de query. URL completa preserva esses caracteres, então a URL continua válida.

Nada do que você digita aqui é armazenado, registrado ou compartilhado.

Codifique texto para uso em uma URL, ou decodifique de volta. Escolha se está codificando um único valor de query ou uma URL inteira, porque os dois exigem escapes diferentes.

Como usar

  1. Escolha codificar ou decodificar.
  2. Ao codificar, escolha Componente para um único valor ou URL completa para um endereço inteiro.
  3. Cole seu texto e copie o resultado.

Por que existem dois modos

A RFC 3986 divide os caracteres que podem aparecer numa URL em dois grupos. Os não reservados - letras, dígitos e os quatro sinais - _ . ~ - sempre significam eles mesmos e nunca são codificados. Os reservados têm significado estrutural: os dois-pontos depois do esquema, as barras entre segmentos do caminho, o ponto de interrogação que abre a query, o & e o = que separam parâmetros, e a cerquilha que inicia o fragmento.

Os dois modos só diferem no que fazem com esse segundo grupo. O modo componente também faz escape dos reservados, que é o que você quer quando o texto vai dentro de um único espaço - um valor de query, um segmento de caminho - e não pode ser lido como estrutura. O modo URL completa os deixa como estão, para que um endereço inteiro sobreviva com esquema, barras e separadores ainda funcionando.

Usar o modo errado costuma ser evidente. Passe um endereço inteiro pelo modo componente e https://example.com vira https%3A%2F%2Fexample.com, que não abre mais. Passe um único valor pelo modo URL completa e um & perdido nele divide seu parâmetro em dois sem avisar.

Os caracteres que dão problema

O espaço é o primeiro que as pessoas encontram. Num caminho ou numa query ele vira %20. Num envio de formulário HTML vira +, porque é isso que as regras mais antigas de application/x-www-form-urlencoded determinam, e as duas convenções continuam em uso diário. É por isso que existe a opção de tratar + como espaço ao decodificar: ligue-a para a query string de um formulário e deixe desligada para um caminho, onde + é um sinal de mais literal e transformá-lo em espaço corrompe o valor.

O & e o = precisam de escape dentro de um valor, senão o servidor divide a query no lugar errado - o caso clássico é um termo de busca ou um bloco Base64 que por acaso contém um deles. A cerquilha nunca chega ao servidor: tudo depois dela é o fragmento, tratado pelo navegador, então um # sem escape dentro de um parâmetro trunca a requisição silenciosamente.

A barra dentro de um valor merece cuidado especial. Codificada como %2F ela é válida, mas vários servidores e proxies a decodificam antes do roteamento, então ela ainda pode ser lida como separador de caminho. Se um valor pode conter barras, colocá-lo na query em vez do caminho evita a discussão inteira.

Codificação dupla

A codificação percentual não é idempotente. O próprio sinal de porcentagem é um caractere que precisa ser codificado, então vira %25, e codificar uma string já codificada transforma %20 em %2520. Essa sequência é a marca visível de uma URL que passou por uma etapa de codificação a mais, e depois que você a vê uma vez, passa a reconhecê-la em todo lugar.

Isso acontece quando um valor é codificado pelo código da aplicação e depois de novo por um framework, um cliente HTTP ou um template que achava que estava recebendo texto bruto. A correção é remover uma das duas etapas, e não decodificar duas vezes do lado que recebe, o que só muda o bug de lugar. Decodificar aqui uma vez por camada, observando se %2520 vira %20 e depois um espaço, mostra quantas camadas havia de fato.

Não ASCII, e o que a codificação percentual não cobre

O texto é convertido para UTF-8 primeiro e depois cada byte é codificado, então um único caractere japonês vira três sequências de escape, e não uma. É isso que o padrão de URL exige, e é por isso que japonês, chinês, coreano, letras acentuadas e emoji fazem a ida e volta sem problemas aqui.

Nomes de domínio são a exceção, e a diferença importa. A parte do host de uma URL não usa codificação percentual: um domínio internacionalizado é convertido com Punycode, gerando um nome que começa com xn--. Codificar um hostname com porcentagem gera algo que parece codificado e não resolve em lugar nenhum. Esta ferramenta cuida só do caminho, da query e do fragmento.

A anatomia de uma URL

Uma URL tem mais partes do que a maioria das pessoas usa: esquema, uma seção userinfo opcional, host, porta opcional, caminho, query e fragmento. Escrita por extenso, https://user:[email protected]:8443/a/b?x=1#top contém todas elas. A forma userinfo está obsoleta para HTTP e os navegadores a removem ou exibem um aviso, justamente porque ela era usada para fazer um host hostil parecer um host conhecido.

Cada pedaço tem regras próprias. O host não diferencia maiúsculas de minúsculas e não pode conter percent-encoding; o caminho diferencia maiúsculas de minúsculas na maioria dos servidores; a query não tem gramática padrão além de ser uma string, e os pares key=value separados por E comercial são convenção, não especificação; e o fragmento nunca sai do navegador.

A resolução de referências relativas é a parte que costuma surpreender. Um link para b/c a partir de /a/page resolve para /a/b/c, mas a partir de /a/page ele resolve para /a/page/b/c - a barra final muda a base. É por isso que uma barra final faltando ou sobrando quebra todos os recursos relativos de uma página, e por isso vale a pena configurar uma vez um redirecionamento canônico entre as duas formas.

Query strings têm convenções, não regras

Não existe padrão para representar um array em uma query string, e é por isso que cada framework faz de um jeito: tags=a&tags=b repete a chave, tags[]=a&tags[]=b acrescenta colchetes e tags=a,b usa um delimitador. As três são URLs válidas e cada uma é interpretada de forma diferente conforme a biblioteca do outro lado.

O mesmo vale para estruturas aninhadas, booleanos e valores vazios. flag= significa false, string vazia ou presente-mas-sem-valor? A resposta é o que o parser que recebe decidir, então uma API que se importa com isso deve documentar o comportamento e validar em vez de supor.

Em JavaScript, URLSearchParams trata corretamente a codificação e as chaves repetidas, e deve ser preferido a montar strings na mão. Vale notar que ele codifica espaços como sinais de mais, seguindo a convenção dos formulários, enquanto encodeURIComponent produz %20 - ambos são decodificados como espaço em uma query string, e apenas um deles em um caminho.

Os problemas de segurança que moram no tratamento de URLs

Um open redirect é um endpoint que envia o visitante para uma URL fornecida em um parâmetro sem verificá-la. Ele é usado para fazer um link de phishing começar em um domínio em que a vítima confia, e continua sendo um achado recorrente em revisões de segurança. A correção é uma lista de destinos permitidos, ou aceitar apenas caminhos em vez de URLs absolutas.

O server-side request forgery é a mesma classe de problema apontada para dentro: o servidor busca uma URL fornecida pelo usuário, e o usuário fornece um endereço interno, um endpoint de metadados da nuvem ou um redirecionamento para um deles. Diferenças de parsing entre bibliotecas já foram exploradas repetidamente aqui, já que dois parsers podem discordar sobre a qual host uma URL forjada se refere.

Ataques de homógrafos exploram os nomes de domínio internacionalizados, em que caracteres cirílicos e latinos que aparecem idênticos na tela produzem hosts diferentes. Os navegadores se defendem exibindo a forma punycode quando um nome mistura sistemas de escrita, e é por isso que um link suspeito às vezes aparece começando com xn-- na barra de endereços. Vale a pena reconhecer esse prefixo.

URLs canônicas, duplicatas e parâmetros de rastreamento

A mesma página normalmente pode ser alcançada por vários endereços: com e sem www, com e sem barra final, por http e por https, com um sufixo index.html e com qualquer quantidade de parâmetros de rastreamento anexados. Para um mecanismo de busca, isso pode parecer páginas distintas com o mesmo conteúdo, o que divide a autoridade que a página conquistou.

Dois mecanismos resolvem isso. Um redirecionamento 301 dá conta das variantes estruturais: escolhe uma forma e manda todo o resto para ela. Um elemento link canonical no head indica o endereço preferido para as variantes que você não pode redirecionar, que são principalmente os casos com parâmetros.

Os parâmetros de rastreamento merecem uma observação específica: utm_source e companhia são anexados pelo sistema de origem e produzem uma URL diferente para cada campanha. Eles pertencem à analytics, não à URL canônica, e removê-los no lado do cliente depois de registrados mantém os links compartilhados limpos. O mesmo vale para os parâmetros fbclid e gclid que algumas plataformas adicionam automaticamente.

Projetar caminhos que envelhecem bem

Uma URL é uma promessa, porque outras pessoas criam links para ela e você não controla esses links. Isso é um argumento a favor de caminhos que descrevem o recurso em vez da implementação: /guides/subnetting em vez de /page.php?id=4718, e nenhuma extensão de arquivo que amarre o endereço à tecnologia que o serve.

Mantenha tudo em minúsculas e separado por hifens. A diferenciação de maiúsculas no servidor significa que /About e /about podem ser páginas diferentes, o que nunca é intencional, e o hífen é o separador de palavras convencional em um slug. Evite datas nos caminhos a menos que o conteúdo seja realmente um arquivo histórico, já que /2024/pricing parece velho um ano depois mesmo quando o conteúdo está atualizado.

Quando uma URL precisar mudar, redirecione a antiga permanentemente e mantenha o redirecionamento por tempo indeterminado. Quebrar links é a única decisão desta lista que não pode ser desfeita do seu lado, porque os links que mais importam são os que estão em sites de que você nunca ouviu falar.

Perguntas frequentes

Qual a diferença entre Componente e URL completa?
Componente usa encodeURIComponent e também escapa os caracteres reservados / ? & = :, o que é correto para um valor de query ou um segmento de caminho. URL completa usa encodeURI e deixa esses caracteres intactos para que o endereço continue válido. Codificar uma URL inteira no modo Componente transforma https:// em https%3A%2F%2F e quebra tudo.
Qual devo usar para um parâmetro de query?
Componente. Um valor que contenha & ou = precisa ser escapado, caso contrário o servidor o lê como separador e divide seu parâmetro no lugar errado.
Por que a decodificação falha com escape malformado?
Um sinal de porcentagem precisa ser seguido de exatamente dois dígitos hexadecimais. Um % solto (como em "100%") ou uma sequência truncada como %E4%B8 não é válida, então a decodificação para em vez de adivinhar.
Quando preciso da opção de tratar + como espaço?
Envios de formulário codificam um espaço como + em vez de %20. Ative a opção ao decodificar uma query string vinda de um formulário HTML. Deixe desligada para segmentos de caminho, onde + é um sinal de mais literal.
Funciona com texto acentuado e outros idiomas?
Sim. O texto é convertido para UTF-8 antes do percent-encoding, então português acentuado, japonês, chinês, coreano e emoji voltam intactos.

Última atualização:

Relatar um problema

Inclua os passos, o resultado esperado e o resultado real. Remova segredos e dados pessoais.

Ferramentas relacionadas