Como Decodificar uma URL em JavaScript (Guia Completo)
O JavaScript oferece decodeURIComponent() para decodificar componentes individuais de uma URI e decodeURI() para decodificar URIs completas. Use try-catch para lidar com URIs malformadas. As APIs URL e URLSearchParams oferecem alternativas mais seguras para analisar URLs.
decodeURIComponent() — Decodificar um Componente de URI
decodeURIComponent() é a principal função para decodificar strings codificadas em URL no JavaScript. Ela decodifica todas as sequências percent-encoded, convertendo-as de volta aos caracteres originais. Use esta função ao decodificar valores de parâmetros de consulta, segmentos de caminho ou qualquer componente isolado de uma URI.
// Decodificação básica
console.log(decodeURIComponent('hello%20world'));
// "hello world"
console.log(decodeURIComponent('price%3D10%26qty%3D2'));
// "price=10&qty=2"
// Decodificando caracteres Unicode
console.log(decodeURIComponent('caf%C3%A9'));
// "cafe" (com acento)
console.log(decodeURIComponent('%E4%B8%AD%E6%96%87'));
// Caracteres chineses
// Decodificando o valor de um parâmetro de consulta a partir de uma URL
const url = 'https://example.com/search?q=C%2B%2B%20%26%20Java';
const params = url.split('?')[1];
const value = params.split('=')[1];
console.log(decodeURIComponent(value));
// "C++ & Java"
decodeURIComponent() decodifica todas as sequências percent-encoded, incluindo aquelas de caracteres reservados como %2F (/) e %3F (?). Esse é o comportamento correto ao trabalhar com componentes individuais de uma URI, mas pode causar problemas se aplicado a uma URL completa.
decodeURI() — Decodificar uma URI Completa
decodeURI() decodifica uma URI completa preservando sua estrutura. Ao contrário de decodeURIComponent(), ela não decodifica sequências que representam caracteres reservados da URI, como %2F (/), %3F (?), %23 (#) e %26 (&).
// decodeURI preserva a estrutura da URI
console.log(decodeURI('https://example.com/my%20page?q=hello%20world'));
// "https://example.com/my page?q=hello world"
// Os espaços são decodificados, mas /, ? e = são preservados
// Compare com decodeURIComponent em uma URL completa
console.log(decodeURIComponent('https%3A%2F%2Fexample.com%2Fpath'));
// "https://example.com/path" - decodifica corretamente se toda a URL foi codificada
// decodeURI não decodifica sequências de caracteres reservados
console.log(decodeURI('path%2Fto%2Ffile'));
// "path%2Fto%2Ffile" - %2F NÃO é decodificado porque / é reservado
console.log(decodeURIComponent('path%2Fto%2Ffile'));
// "path/to/file" - %2F É decodificado
Use decodeURI() quando quiser tornar uma URL mais legível (para fins de exibição, por exemplo) sem alterar sua estrutura. Para a maioria dos casos de uso programáticos, você vai querer decodeURIComponent() aplicado a componentes individuais.
Lidando com URIs Malformadas
Tanto decodeURI() quanto decodeURIComponent() lançam um URIError quando encontram sequências percent-encoded inválidas. Isso acontece com sinais de porcentagem isolados, sequências incompletas ou sequências de bytes UTF-8 inválidas. Sempre envolva operações de decodificação em um bloco try-catch ao trabalhar com URLs fornecidas por usuários ou externas.
// Estes lançam URIError: URI malformed
try {
decodeURIComponent('%'); // porcentagem isolada
} catch (e) {
console.error(e.message); // "URI malformed"
}
try {
decodeURIComponent('%2'); // sequência incompleta
} catch (e) {
console.error(e.message); // "URI malformed"
}
// Função de decodificação segura
function safeDecode(str) {
try {
return decodeURIComponent(str);
} catch (e) {
console.warn('Failed to decode:', str);
return str; // retorna a string original em caso de falha
}
}
// Corrige sequências de porcentagem malformadas antes de decodificar
function fixAndDecode(str) {
// Substitui % isolado por %25 (sinal de porcentagem codificado)
const fixed = str.replace(/%(?![0-9A-Fa-f]{2})/g, '%25');
return decodeURIComponent(fixed);
}
console.log(fixAndDecode('100% complete'));
// "100% complete"
Usando a API URL (Recomendado)
As modernas APIs URL e URLSearchParams oferecem uma maneira mais segura e estruturada de analisar e decodificar URLs. Elas lidam com a codificação e a decodificação automaticamente, reduzindo o risco de erros.
// Analisa uma URL e acessa seus componentes (decodificados automaticamente)
const url = new URL('https://example.com/path%20here?q=hello%20world&lang=en');
console.log(url.pathname); // "/path here" (decodificado)
console.log(url.search); // "?q=hello%20world&lang=en" (bruto)
// URLSearchParams decodifica automaticamente os valores dos parâmetros
console.log(url.searchParams.get('q')); // "hello world"
console.log(url.searchParams.get('lang')); // "en"
// Itera sobre todos os parâmetros
for (const [key, value] of url.searchParams) {
console.log(key, '=', value);
}
// q = hello world
// lang = en
// URLSearchParams trata + como espaço (codificação de formulário)
const formParams = new URLSearchParams('q=hello+world&lang=en');
console.log(formParams.get('q')); // "hello world"
// Construindo URLs com codificação automática
const newUrl = new URL('https://example.com/search');
newUrl.searchParams.set('q', 'C++ & Java');
newUrl.searchParams.set('page', '1');
console.log(newUrl.toString());
// "https://example.com/search?q=C%2B%2B+%26+Java&page=1"
Erros Comuns de Decodificação
Erro 1: Decodificar uma URL completa com decodeURIComponent(). Isso pode quebrar a estrutura da URL se ela contiver caracteres reservados codificados. Um %2F em um valor de consulta se tornaria uma /, potencialmente alterando o significado da URL.
Erro 2: Decodificação dupla. Se uma string já foi decodificada uma vez, decodificá-la novamente pode produzir resultados inesperados ou erros. Por exemplo, a string %2520 é decodificada primeiro para %20 e depois para um espaço. Se você espera apenas um nível de codificação, a decodificação dupla corrompe os dados.
// Problema de decodificação dupla
const encoded = '%2520'; // Isto é um %20 codificado
console.log(decodeURIComponent(encoded)); // "%20" (correto - um nível)
console.log(decodeURIComponent(decodeURIComponent(encoded))); // " " (decodificado duas vezes!)
// Verifica se uma string precisa ser decodificada antes de decodificá-la
function needsDecoding(str) {
return str !== decodeURIComponent(str);
}
Erro 3: Não tratar o sinal +. decodeURIComponent() não converte + em espaços. Se você estiver decodificando dados no formato form-urlencoded, precisa substituir + por espaços primeiro, ou usar URLSearchParams, que faz isso automaticamente.
// decodeURIComponent NÃO decodifica + como espaço
console.log(decodeURIComponent('hello+world'));
// "hello+world" (não "hello world"!)
// Solução: substitua + antes de decodificar
function decodeFormValue(str) {
return decodeURIComponent(str.replace(/\+/g, ' '));
}
console.log(decodeFormValue('hello+world'));
// "hello world"
// Ou use URLSearchParams (trata + automaticamente)
const params = new URLSearchParams('q=hello+world');
console.log(params.get('q'));
// "hello world"