Cookies para estatística e publicidade
Usamos cookies de estatística e de publicidade, ambos enviados ao Google. Recusar não muda nada do que você vê.Ler a página de privacidade
Cole uma string e receba ela escapada em porcentagem para usar numa URL. A única decisão que importa é oferecida como escolha em vez de ser adivinhada: se você está codificando um valor que vai dentro de um endereço, ou um endereço inteiro cujas barras e interrogações são estrutura e precisam sobreviver. Quem confunde as duas coisas recebe uma URL que parece certa e leva para outro lugar.
Onde roda
Nada é enviado, porque não há arquivo — a conta é feita nesta página.
Sem fila, sem conta
Responde na velocidade da sua máquina e nunca pergunta quem você é.
Quantas vezes quiser
Nada é contado nem limitado — responder de novo não nos custa nada.
Uma URL é feita de partes, e os caracteres que separam essas partes — `/`, `?`, `&`, `=`, `#` — são estrutura quando estão cumprindo essa função e são dado quando não estão. Codificar um endereço inteiro precisa deixá-los em paz, ou ele deixa de ser um endereço; codificar um valor solto precisa escapá-los, ou o valor termina e começa outra coisa.
É exatamente a diferença entre `encodeURI` e `encodeURIComponent`, e daí sai a maioria dos parâmetros de redirecionamento quebrados que existem na web: um `?voltar=https://exemplo.com/a?b=c` em que a segunda interrogação nunca foi escapada, de modo que tudo o que vem depois pertence à URL de fora. O link funciona no teste, onde o destino não tem query string, e falha em produção, onde tem.
Uma sequência de porcentagem é um `%` seguido de dois dígitos hexadecimais e designa um byte. Caracteres fora do ASCII precisam de várias: um `ç` é `%C3%A7` e não `%E7`, porque o UTF-8 escreve ele em dois bytes. Um emoji precisa de quatro sequências.
A velha função `escape()` produzia `%E7` e está obsoleta justamente por isso — ela é anterior à decisão de que a web fala UTF-8. A saída dela ainda aparece em código antigo e em algumas integrações herdadas, onde decodifica para o caractere errado em qualquer coisa que não seja um backend em Latin-1. Aqui é UTF-8 do começo ao fim.
O `encodeURIComponent` deixa sem escapar o ponto de exclamação, o apóstrofo, os dois parênteses e o asterisco. A RFC 3986 lista os cinco como reservados, então um codificador estritamente conforme escapa — e os dois discordam em cinco caracteres que aparecem o tempo todo em texto comum.
Só se percebe quando há uma assinatura envolvida. O OAuth 1.0 e o AWS Signature versão 4 calculam um hash sobre a string codificada, de modo que um único apóstrofo sem escapar muda o hash e a requisição é recusada — com um erro sobre credencial, que manda você procurar no lugar errado. A opção estrita daqui escapa os cinco.
Os dois aparecem e não obedecem à mesma regra. `%20` é codificação de porcentagem e está correto em qualquer parte de uma URL. O sinal de mais vem do `application/x-www-form-urlencoded`, o formato em que um formulário HTML envia, onde um espaço é escrito como `+` — uma convenção anterior à especificação atual que sobrevive porque os formulários sobrevivem.
Num caminho, `+` é um mais de verdade. Num query string, a maioria dos servidores lê como espaço, porque é o que a codificação de formulário diz — de modo que um mais real dentro de um valor precisa ser escrito `%2B` ou ele some. Este codificador produz `%20`, que não é ambíguo em nenhum dos dois lugares.
Codificar uma string já codificada escapa o próprio `%`, então `%20` vira `%2520`. Para nenhuma das peças envolvidas isso é um erro — é uma codificação perfeitamente válida do texto literal «%20» —, e por isso a dupla codificação sobrevive até o ponto em que uma pessoa lê `Olá%20mundo` num título de página.
O sinal é um `%25` onde deveria haver um `%`. Se você vê um, alguma coisa na esteira está codificando um valor que já estava codificado, normalmente porque um framework faz por você e um template repete. A solução é remover uma das duas etapas, não decodificar duas vezes no fim.
As letras, os dígitos e os quatro caracteres `-`, `_`, `.` e `~` são chamados de «unreserved» na RFC 3986 e não devem ser escapados nunca. Um codificador que produza `%2E` no lugar de um ponto não é mais rigoroso: está errado, porque alguns sistemas normalizam de volta e outros não, e assim duas URLs que deveriam ser a mesma deixam de ser.
Na prática: uma string codificada com muitíssimas sequências de porcentagem, quando o texto é quase todo letras, costuma vir de uma ferramenta que codifica demais. É inofensivo até alguém calcular uma assinatura ou uma chave de cache sobre aquilo — e aí vira o motivo pelo qual dois sistemas não se entendem.
Cada byte escapado ocupa três caracteres, então um texto que é quase todo ASCII cresce pouco e um que tem acento em cada palavra cresce bem mais: cada `ç`, cada `ã` e cada `é` viram dois bytes e portanto seis caracteres. «Ação» sai com dezoito caracteres.
Isso importa quando o valor tem que caber em algum lugar. Um parâmetro que passava confortavelmente em inglês pode estourar um limite de comprimento com o mesmo conteúdo em português, e o sintoma não é um erro claro e sim um valor cortado no meio de uma sequência de porcentagem — que a outra ponta então recusa como malformado.
Não existe limite na especificação, e existem limites em toda implementação real. Os navegadores lidam bem com endereços de alguns milhares de caracteres e param de lidar em algum ponto acima disso; os servidores costumam recusar antes: a configuração padrão do Apache corta a linha de requisição em pouco mais de oito mil caracteres, e a do nginx é da mesma ordem.
A consequência prática é que dados grandes não pertencem a um query string. Se um valor codificado passa de alguns milhares de caracteres, a resposta é um POST com corpo, ou guardar o dado e passar um identificador — e não descobrir o teto em produção com um erro que não diz que o problema foi o comprimento.
Tudo o que vem depois do `#` fica no navegador. Não aparece em nenhuma requisição, não chega a nenhum servidor e não consta em nenhum log de acesso. É uma propriedade do HTTP, não uma função de privacidade, e corta nos dois sentidos.
É útil porque um valor no fragmento não chega ao servidor — historicamente, o motivo pelo qual os tokens de OAuth viajavam ali. É incômodo porque ele mesmo assim fica no histórico do navegador, na cadeia de referrer de alguns scripts e em qualquer link compartilhado. «Não chega ao servidor» não significa «é privado».
Um domínio com cedilha ou com til não é escapado: ele é convertido para Punycode. `coração.example` vira `xn--corao-dra1a.example`, que é a forma que existe de verdade no DNS, porque o sistema de nomes só conhece ASCII.
Um codificador que trate o host como se fosse um valor produz um endereço que nenhum DNS resolve. Por isso aqui o modo de endereço inteiro deixa o host intacto — e por isso, se você está montando uma URL com um domínio acentuado, a conversão do host é um passo à parte e não faz parte desta operação.
O que se codifica costuma ir parar numa URL, e URLs ficam no log do servidor, no histórico do navegador e no cabeçalho de referrer do clique seguinte. Se o valor carrega um e-mail, um CPF ou um termo de busca pessoal, ele está em vários lugares assim que for usado.
A parte que esta página resolve é que a codificação acontece na sua máquina: o valor não é compartilhado conosco. O que ela não resolve é a outra parte, e isso merece ser dito aqui — o lugar mais frequente em que um dado pessoal acaba registrado sem querer é um parâmetro de URL.
Se o texto é um valor que vai dentro de um endereço, o primeiro: ele escapa ? & = / e #. Se é um endereço inteiro, o segundo, que mantém tudo isso porque ali é estrutura. O terceiro só é necessário quando há assinatura envolvida.
Porque a codificação de porcentagem transporta bytes e o UTF-8 escreve o ç em dois: %C3%A7. A forma antiga %E7 vinha do escape(), que está obsoleto e decodifica para o caractere errado em qualquer sistema que não seja Latin-1.
Que ela foi codificada duas vezes: o %20 passou de novo por um codificador e o % dele foi escapado. A solução é remover uma das duas etapas, não decodificar duas vezes no fim.
%20 está correto em qualquer parte de uma URL. O + só significa espaço num query string, por herança da codificação de formulário; num caminho é um mais de verdade. Aqui sai %20, que não é ambíguo.
Não. Ele é codificado nesta página. Considere, porém, que depois de usada a URL o valor fica em log de servidor, no histórico e no cabeçalho de referrer.