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.
| Regra | Escapa / ? & = # | O espaço passa a | Usar para |
|---|---|---|---|
encodeURIComponent | Sim | %20 | Um valor que vai para dentro de um URL |
encodeURI | Não | %20 | Arrumar um URL completo |
| Codificação de formulário | Sim | + | 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%20cakeUm parâmetro, valor intacto. Codificado com encodeURI, o e comercial sobrevive tal e qual:
/search?q=coffee%20&%20cakeAgora 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++ dá 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=2Todas 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ência | Carácter | Porque importa |
|---|---|---|
%20 | espaço | De 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 |
%00 | nulo | Quase 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.
