Erros de codificação de URL que os desenvolvedores ainda cometem (e corrigem)

Bugs de codificação de URL são sutis, persistentes e frequentemente descobertos na produção. Um extraviado %20, um e comercial com codificação dupla ou um confuso + vs space pode interromper chamadas de API, corromper dados de rastreamento e criar vulnerabilidades de segurança. Vamos corrigir os mais comuns.
Teste sua codificação com nosso Codificador/Decodificador de URL ferramenta – cole qualquer string e veja o resultado codificado instantaneamente.
encodeURI vs encodeURIComponent
JavaScript tem duas funções de codificação integradas, e usar a errada é a fonte número 1 de bugs:
| Função | Codifica | Conservas | Usar para |
|---|---|---|---|
codificarURI | Espaços, não ASCII | : / ? #[ ]@ ! $ & ' ( ) * + , ; = | Codificando um URL completo |
codificarURIComponent | Tudo acima +: / ? #@! $ & ' ( ) * + , ; = | Apenas - _ . ~ e alfanuméricos | Codificando um valor de parâmetro de consulta |
// ERRADO — encodeURI preserva & nos valores da consulta
const url = 'https://api.example.com/search?q=' + encodeURI('tom & jerry');
// Resultado: https://api.example.com/search?q=tom%20&%20jerry
// O & é preservado — agora parece um parâmetro separado! // CORRETO
const url = 'https://api.example.com/search?q=' + encodeURIComponent('tom & jerry');
// Resultado: https://api.example.com/search?q=tom%20%26%20jerry
Regra prática: Usar codificarURIComponent para valores individuais. Usar codificarURI somente quando você tiver um URL completo que precise apenas de caracteres não ASCII codificados.
Bugs de codificação dupla
A codificação dupla acontece quando uma string já codificada é codificada novamente:
const nome = 'olá mundo';
const codificado = encodeURIComponent(nome); // olá%20mundo
const dobrado = encodeURIComponent(codificado); // olá%2520mundo
// %25 é a codificação do próprio %!
Isso normalmente ocorre quando:
- Uma estrutura codifica automaticamente os parâmetros de consulta e você também os pré-codifica
- Um URL é codificado antes de ser armazenado e, em seguida, codificado novamente quando recuperado
- O middleware processa a URL em múltiplas camadas, cada uma adicionando codificação
Detecção
Procurar %25 em URLs — quase sempre é um sinal de codificação dupla. A sequência %2520(espaço de codificação dupla) é o clássico revelador.
A confusão + vs %20
Em envios de formulários HTML (aplicativo/x-www-form-urlencoded), os espaços tornam-se +. Na codificação percentual padrão (RFC 3986), os espaços tornam-se %20.
Isso é importante porque:
decodificarURIComponentfaz não decodificar+de volta ao espaço - deixa-o literalmente+- Estruturas de back-end podem ou não decodificar automaticamente
+dependendo do analisador - Se sua API espera
%20mas recebe+, as pesquisas por "vermelho+carro" retornam resultados para "vermelho+carro" (com um sinal de adição literal) em vez de "carro vermelho"
// Decodificação segura que lida com + e %20
função safeDecodeParam(valor) { retornar decodeURIComponent(value.replace(/\+/g, '%20'));
} Casos extremos UTF-8
Caracteres não-ASCII como é, ü, 日本語, e os emojis devem ser codificados por porcentagem como suas sequências de bytes UTF-8:
encodeURIComponent('café') // caf%C3%A9
encodeURIComponent('日本語') // %E6%97%A5%E6%9C%AC%E8%AA%9E
encodeURIComponent('🔒') //%F0%9F%94%92
Os problemas surgem quando:
- O servidor espera Latin-1, mas recebe UTF-8 (mojibake — caracteres ilegíveis)
- As colunas do banco de dados não estão definidas como UTF-8, truncando silenciosamente caracteres multibyte
- Os arquivos de log interpretam strings codificadas com conjunto de caracteres errado
Armadilhas de URL de redirecionamento e retorno de chamada
Retornos de chamada OAuth e URLs de redirecionamento são especialmente propensos a erros de codificação:
// Construindo um redirecionamento OAuth
const redirecionaUri = 'https://myapp.com/callback?source=oauth';
const authUrl = `https://provider.com/auth?redirect_uri=${encodeURIComponent(redirectUri)}`;
// Correto: todo o URL de retorno de chamada (incluindo o seu próprio?) é codificado como um único valor de parâmetro
Erros comuns:
- Não codificando o
redirecionamento_uriem absoluto - o?no retorno de chamada divide o URL pai - Codificando o
redirecionamento_uriparcialmente – codificando o caminho, mas não a consulta - Codificando todo o URL de autenticação em vez de apenas o valor do parâmetro
Esses bugs geralmente criam vulnerabilidades de redirecionamento abertas que os invasores exploram para phishing.
Lista de verificação de depuração
Quando um URL não estiver funcionando conforme o esperado, verifique-os na ordem:
- Procure por %25— indica codificação dupla
- Verifique + vs %20— os espaços são tratados de forma consistente?
- Inspecionar solicitação bruta- use a guia Rede DevTools do navegador para ver o URL codificado real enviado
- Teste com caracteres especiais- tentar
&=? #/em valores para ver se eles quebram a estrutura do URL - Verifique o tipo de conteúdo- o servidor está analisando como
aplicativo/x-www-form-urlencodedouaplicativo/json? - Verifique a decodificação no servidor— registre os valores brutos e decodificados no lado do servidor
Funções auxiliares seguras
// Construa uma string de consulta com segurança
função buildQueryString(params) { retornar Object.entries (params) .map(([chave, valor]) => `${encodeURIComponent(chave)}=${encodeURIComponent(valor)}` ) .juntar('&');
} // Use URLSearchParams (navegadores modernos + Node.js)
const params = novo URLSearchParams({ q: 'tom & jerry', página: '1' });
const url = `https://api.example.com/search?${params}`;
// Correto: trata a codificação automaticamente
Melhor prática: Usar URLSearchParams ou URL construtor em vez de concatenação manual de strings. Eles lidam com a codificação corretamente por padrão.
Perguntas frequentes
Por que + se torna um espaço?
Este é um legado da codificação de formulário HTML (aplicativo/x-www-form-urlencoded), onde os espaços são codificados como +. Na codificação percentual padrão (RFC 3986), os espaços são %20. O + A convenção se aplica apenas a strings de consulta em envios de formulários, não a segmentos de caminho ou outras partes de URL.
Como codifico URLs aninhados corretamente?
Usar codificarURIComponent no URL interno antes de colocá-lo no parâmetro de consulta do URL externo. Isso codifica caracteres como :/? que de outra forma seria interpretado como parte da estrutura do URL externo.
Por que as assinaturas quebram após a codificação do URL?
As assinaturas são calculadas em sequências exatas de bytes. Se você assinar uma string antes da codificação (ou após a decodificação), mas verificá-la na forma codificada (ou vice-versa), os bytes serão diferentes e a assinatura falhará. Sempre normalize a codificação antes de assinar.
Ferramentas e artigos relacionados
- Codificador/Decodificador de URL— teste a codificação em tempo real
- Erros de segurança do JWT- a codificação também é importante para o manuseio de tokens
- Correção de incompatibilidade de soma de verificação— ao codificar alterações, hashes de arquivos corrompidos