Codificador e decodificador de URL

Os três tipos de codificação por porcentagem lado a lado, para você ver qual quer.

Três regras, e escolher a errada é o defeito

A codificação percentual substitui um carácter por % seguido do valor do seu byte em hexadecimal. Simples. O que dá problemas é haver três opiniões diferentes sobre que caracteres precisam de ser substituídos, e elas discordam precisamente nos caracteres que importam.

RegraEscapa / ? & = #O espaço passa aUsar para
encodeURIComponentSim%20Um valor que vai para dentro de um URL
encodeURINão%20Arrumar um URL completo
Codificação de formulárioSim+Aquilo que um formulário HTML envia

É exactamente por isso que a ferramenta mostra as três de uma vez. Lê-las lado a lado é mais rápido do que decidir em abstracto qual queria.

O erro que isto evita

Suponha que um valor de pesquisa é coffee & cake. Codificado como componente passa a coffee%20%26%20cake, e o URL fica:

/search?q=coffee%20%26%20cake

Um parâmetro, valor intacto. Codificado com encodeURI, o e comercial sobrevive tal e qual:

/search?q=coffee%20&%20cake

Agora o servidor vê dois parâmetros — q é «coffee » e há um segundo, vazio, chamado « cake». Nada dá erro. A pesquisa limita-se a devolver, em silêncio, os resultados errados, e este é o tipo de defeito que sobrevive à revisão porque o URL parece bem.

O + que não é um mais

A outra fonte fiável de confusão. Em dados codificados como formulário, + significa espaço, e um sinal de mais literal tem de ser %2B. Portanto descodificar C%2B%2B com a regra de formulário dá C++, mas descodificar C++C — e dois espaços, e o nome da linguagem desapareceu.

Isto morde com mais força nos números de telefone. +44 20 7946 0958 submetido através de um formulário e descodificado com a regra errada torna-se 44 20 7946 0958, perdendo o indicativo do país, e nada, em lado nenhum, reporta um erro.

O que fazer em vez de codificar à mão

Em JavaScript, construa as cadeias de consulta com URLSearchParams em vez de as concatenar. Aplica a regra certa a cada valor e lida com chaves repetidas:

const url = new URL('https://example.com/search');
url.searchParams.set('q', 'coffee & cake');
url.searchParams.set('page', '2');
// https://example.com/search?q=coffee+%26+cake&page=2

Todas as outras linguagens têm um equivalente, e qualquer um deles é mais fiável do que decidir carácter a carácter. Esta página serve para as vezes em que está a ler um URL que alguém lhe enviou, ou a depurar um que já correu mal.

Ler um URL codificado

Vale a pena reconhecer algumas sequências à primeira vista, porque aparecem constantemente nos registos:

SequênciaCarácterPorque importa
%20espaçoDe longe a mais comum
%2F/Uma barra codificada num caminho é muitas vezes uma tentativa de travessia de directórios
%3A:Comum em URL codificados dentro de parâmetros de redireccionamento
%25%A dupla codificação aparece como %2520
%00nuloQuase nunca é legítimo

O %2520 em particular vale a pena conhecer: é um %20 que foi codificado uma segunda vez. Normalmente significa que um valor passou por duas camadas que o codificaram cada uma, e é a assinatura de uma cadeia de redireccionamentos ou de um proxy a fazer o que não deve.

Relacionado

Para codificar bytes em vez de escapar texto, o Base64 é a tarefa diferente. Se o valor descodificado for afinal JSON, o formatador lê-o, e se for um token, o descodificador de JWT trata dele.

Perguntas sobre codificação

Qual é a diferença entre encodeURI e encodeURIComponent?

O encodeURIComponent escapa os caracteres com significado estrutural num URL — / ? & = # : e outros — porque parte do princípio de que está a codificar um valor que vai ficar dentro de um URL. O encodeURI deixa-os em paz, porque assume que lhe entregaram um URL inteiro que só precisa de ser arrumado. Codificar um parâmetro de consulta com encodeURI é o erro habitual: um & dentro do valor sobrevive e parte o seu parâmetro em dois sem avisar.

Porque é que um espaço é umas vezes %20 e outras +?

Ambos estão certos no seu contexto. %20 é a codificação percentual geral do espaço e funciona em qualquer parte de um URL. A convenção do + vem de application/x-www-form-urlencoded, o formato em que os formulários HTML são submetidos, onde + significa espaço e um sinal de mais literal tem de se escrever %2B. Logo, um espaço num caminho é %20 e um espaço em dados de formulário submetidos é +. Descodificar dados de formulário com a regra errada transforma cada sinal de mais no texto do utilizador num espaço.

Deu-me um erro «URI malformed». O que o provoca?

Um sinal de percentagem que não é seguido por dois dígitos hexadecimais. Normalmente é um % literal num texto que nunca foi codificado — um código de desconto como «50% off» chega, porque %20 é lido como sequência de escape e %off não é válido. Uma percentagem literal tem de se escrever %25. A outra causa é a dupla descodificação: descodificar duas vezes o que foi codificado uma só acaba por esbarrar num % que era para ficar.

Devo codificar o URL inteiro ou apenas os valores?

Apenas os valores, praticamente sempre. Construa o URL pela sua estrutura e codifique cada parâmetro à medida que o insere — em JavaScript, o URLSearchParams faz isso por si e é mais fiável do que codificar à mão. Codificar um URL completo só faz sentido quando lhe entregaram um já malformado e o está a remendar.

Codificar um URL torna-o seguro?

Não. A codificação percentual é uma questão de sintaxe, não de segurança — garante que um valor sobrevive a ser colocado num URL sem alterar a estrutura desse URL. Nada faz quanto ao sítio para onde o URL aponta, e não é defesa contra injecção: um valor correctamente codificado para um URL continua perigoso se depois for inserido em HTML ou SQL sem o escape próprio desses contextos.

Última revisão . Encontrou algo desactualizado? Diga-nos.