URL Encode JavaScript — Guia encodeURIComponent()
Use o Codificador de URL Online gratuito diretamente no seu navegador — sem instalação.
Experimentar Codificador de URL Online online →Quando você constrói uma URL de busca, passa um caminho de redirecionamento como parâmetro de query, ou monta uma requisição de autorização OAuth, caracteres especiais como &, = e espaços vão corromper silenciosamente a URL a menos que você os codifique antes. O JavaScript oferece três abordagens nativas — encodeURIComponent(), encodeURI() e URLSearchParams — cada uma projetada para um caso de uso diferente, e escolher a errada é a causa raiz da maioria dos bugs de codificação que já encontrei em revisões de código. Para uma codificação rápida sem escrever código, o Codificador de URL do ToolDeck faz isso instantaneamente no navegador. Este guia cobre as três abordagens em profundidade (JavaScript ES2015+ / Node.js 10+): quando usar cada uma, como diferem para espaços e caracteres reservados, padrões reais com Fetch e APIs, uso na CLI, e os quatro erros que causam os bugs de produção mais sutis.
- ✓encodeURIComponent() é a escolha certa para codificar valores de parâmetros individuais — codifica todos os caracteres exceto A–Z, a–z, 0–9 e - _ . ! ~ * ' ( )
- ✓encodeURI() codifica uma URL completa preservando os caracteres estruturais (/ ? # & = :) — nunca a use para valores individuais
- ✓URLSearchParams codifica pares chave-valor automaticamente usando o formato application/x-www-form-urlencoded, onde espaços viram + em vez de %20
- ✓A dupla codificação é o bug de produção mais comum: encodeURIComponent(encodeURIComponent(value)) transforma %20 em %2520
- ✓A biblioteca qs lida nativamente com objetos aninhados e arrays em query strings — URLSearchParams da stdlib não faz isso
O que é codificação de URL?
A codificação de URL (formalmente chamada de codificação percentual, definida na RFC 3986) converte caracteres não permitidos ou com significado especial em uma URL para uma representação segura. Cada byte inseguro é substituído por um sinal de porcentagem seguido de dois dígitos hexadecimais — o código ASCII do caractere. Um espaço vira %20, um e comercial vira %26, uma barra vira %2F.
Os caracteres que são sempre seguros e nunca codificados são chamados de caracteres não reservados: letras A–Z e a–z, dígitos 0–9, e os quatro símbolos - _ . ~. Todo o resto deve ser codificado quando usado como dado, ou tem um papel estrutural na URL (como / separando segmentos de caminho ou &separando parâmetros de query). A consequência prática: um nome de produto como “Teclado Sem Fio & Mouse” em um parâmetro de query destrói a estrutura da URL se passado sem codificação.
https://shop.example.com/search?q=Wireless Keyboard & Mouse&category=peripherals
https://shop.example.com/search?q=Wireless%20Keyboard%20%26%20Mouse&category=peripherals
encodeURIComponent() — A função certa para parâmetros de query
encodeURIComponent() é o carro-chefe da codificação de URL em JavaScript. Ela codifica todos os caracteres exceto o conjunto não reservado (A–Z, a–z, 0–9, - _ . ! ~ * ' ( )). Criticamente, codifica todos os caracteres com significado estrutural em URLs — &, =, ?, #, / — tornando-a segura para uso em valores de parâmetros. Não é necessária nenhuma importação; é uma função global disponível em todos os ambientes JavaScript.
Exemplo mínimo funcional
// Encode a search query parameter that contains special characters
const searchQuery = 'Wireless Keyboard & Mouse'
const filterStatus = 'in-stock'
const maxPrice = '149.99'
const searchUrl = `https://shop.example.com/products?` +
`q=${encodeURIComponent(searchQuery)}` +
`&status=${encodeURIComponent(filterStatus)}` +
`&maxPrice=${encodeURIComponent(maxPrice)}`
console.log(searchUrl)
// https://shop.example.com/products?q=Wireless%20Keyboard%20%26%20Mouse&status=in-stock&maxPrice=149.99Codificando uma URL de redirecionamento como parâmetro de query
// The redirect destination is itself a URL — it must be fully encoded
// or the outer URL parser will misinterpret its ? and & as its own
const redirectAfterLogin = 'https://dashboard.internal/reports?view=weekly&team=platform'
const loginUrl = `https://auth.company.com/login?next=${encodeURIComponent(redirectAfterLogin)}`
console.log(loginUrl)
// https://auth.company.com/login?next=https%3A%2F%2Fdashboard.internal%2Freports%3Fview%3Dweekly%26team%3Dplatform
// Decoding on the receiving end
const params = new URLSearchParams(window.location.search)
const next = params.get('next') // Automatically decoded
const nextUrl = new URL(next!) // Safe to parse
console.log(nextUrl.hostname) // dashboard.internalCodificando caracteres não-ASCII e Unicode
// encodeURIComponent handles Unicode natively in all modern environments
// Each UTF-8 byte of the character is percent-encoded
const customerName = 'Araújo, João'
const productTitle = '東京 wireless adapter'
const reviewText = 'Muito bom — funciona perfeitamente'
console.log(encodeURIComponent(customerName))
// Ara%C3%BAjo%2C%20Jo%C3%A3o
console.log(encodeURIComponent(productTitle))
// %E6%9D%B1%E4%BA%AC%20wireless%20adapter
console.log(encodeURIComponent(reviewText))
// Muito%20bom%20%E2%80%94%20funciona%20perfeitamente
// Decoding back
console.log(decodeURIComponent('Ara%C3%BAjo%2C%20Jo%C3%A3o'))
// Araújo, JoãoencodeURIComponent() usa a codificação interna UTF-16 do motor JavaScript, e depois codifica cada byte UTF-8 do caractere separadamente. Um caractere como ü (U+00FC) é codificado como %C3%BC porque sua representação UTF-8 tem dois bytes: 0xC3 e 0xBC. Isso é correto e segue o padrão URI — os servidores devem decodificar a sequência de bytes UTF-8 de volta ao codepoint original.Funções de codificação de URL em JavaScript — Referência de caracteres
As três abordagens de codificação nativas diferem exatamente em quais caracteres codificam. A tabela abaixo mostra a saída para os caracteres mais problemáticos:
| Caractere | Papel na URL | encodeURIComponent() | encodeURI() | URLSearchParams |
|---|---|---|---|---|
| Space | separador de palavras | %20 | %20 | + |
| & | separador de parâmetros | %26 | mantido | %26 |
| = | chave=valor | %3D | mantido | %3D |
| + | espaço codificado (form) | %2B | %2B | %2B |
| ? | início da query | %3F | mantido | %3F |
| # | fragmento | %23 | mantido | %23 |
| / | separador de caminho | %2F | mantido | %2F |
| : | esquema / porta | %3A | mantido | %3A |
| @ | separador de autenticação | %40 | mantido | %40 |
| % | literal de porcentagem | %25 | %25 | %25 |
| ~ | não reservado | mantido | mantido | mantido |
A coluna crítica é encodeURIComponent() versus encodeURI() para & e =: encodeURI() os deixa intactos, o que é correto ao codificar uma URL completa, mas catastrófico ao codificar um valor que contém esses caracteres.
encodeURI() — Quando preservar a estrutura da URL
encodeURI() é projetada para codificar uma URL completa— ela preserva todos os caracteres que são partes estruturais válidas de uma URI: o esquema (https://), o host, separadores de caminho, delimitadores de query e o identificador de fragmento. Use-a quando receber uma URL que pode conter espaços ou caracteres não-ASCII em seus segmentos de caminho, mas você precisa manter a estrutura intacta.
Saneando uma URL fornecida pelo usuário
// A URL pasted from a document with spaces in the path and non-ASCII chars const rawUrl = 'https://cdn.example.com/assets/product images/München chair.png' const safeUrl = encodeURI(rawUrl) console.log(safeUrl) // https://cdn.example.com/assets/product%20images/M%C3%BCnchen%20chair.png // encodeURIComponent would break it — it encodes the :// and all / characters const broken = encodeURIComponent(rawUrl) console.log(broken) // https%3A%2F%2Fcdn.example.com%2Fassets%2Fproduct%20images%2FM%C3%BCnchen%20chair.png // ↑ Not a valid URL — the scheme and slashes are destroyed
URL geralmente é uma escolha melhor do que encodeURI() para lidar com strings de URL fornecidas pelo usuário — ele normaliza a URL, valida a estrutura e oferece uma API limpa para acessar cada componente. Reserve encodeURI() para casos onde você precisa de um resultado em string e já sabe que a entrada é estruturalmente uma URL válida.URLSearchParams — A abordagem moderna para query strings
URLSearchParams é a forma idiomática de construir e analisar query strings em JavaScript moderno. Está disponível globalmente em todos os navegadores modernos e Node.js 10+, e lida com a codificação automaticamente — você trabalha com pares chave-valor simples e ele produz a saída correta. Um detalhe importante: ele segue a especificação application/x-www-form-urlencoded, que codifica espaços como + em vez de %20. Isso é correto e amplamente suportado, mas você deve estar ciente disso quando seu servidor espera um formato específico.
Construindo uma URL de requisição de busca
// Building a search API URL with multiple parameters
const filters = {
query: 'standing desk',
category: 'office-furniture',
minPrice: '200',
maxPrice: '800',
inStock: 'true',
sortBy: 'price_asc',
}
const params = new URLSearchParams(filters)
const apiUrl = `https://api.example.com/v2/products?${params}`
console.log(apiUrl)
// https://api.example.com/v2/products?query=standing+desk&category=office-furniture&minPrice=200&maxPrice=800&inStock=true&sortBy=price_asc
// Appending additional params after construction
params.append('page', '2')
params.append('tag', 'ergonomic & adjustable')
console.log(params.toString())
// query=standing+desk&...&tag=ergonomic+%26+adjustableAnalisando uma query string recebida
// Both browser (window.location.search) and Node.js (req.url) scenarios
function parseWebhookCallbackUrl(rawSearch: string) {
const params = new URLSearchParams(rawSearch)
return {
eventId: params.get('event_id'), // null if missing
timestamp: Number(params.get('ts')),
signature: params.get('sig'),
redirectUrl: params.get('redirect'), // Automatically decoded
tags: params.getAll('tag'), // Handles repeated keys
}
}
const callbackQuery = '?event_id=evt_9c2f&ts=1717200000&sig=sha256%3Dabc123&redirect=https%3A%2F%2Fdashboard.internal%2F&tag=payment&tag=webhook'
const parsed = parseWebhookCallbackUrl(callbackQuery)
console.log(parsed.redirectUrl) // https://dashboard.internal/
console.log(parsed.tags) // ['payment', 'webhook']Como codificar parâmetros de URL em requisições Fetch do JavaScript
O lugar mais comum onde a codificação de URL aparece em código de produção é dentro de chamadas fetch() — seja construindo a URL da requisição ou enviando dados de formulário no corpo da requisição. Cada cenário tem sua própria abordagem correta.
Requisição GET — codificando parâmetros de query
async function searchInventory(params: {
sku?: string
warehouse: string
minStock: number
updatedAfter?: Date
}): Promise<{ items: unknown[]; total: number }> {
const searchParams = new URLSearchParams()
if (params.sku) searchParams.set('sku', params.sku)
searchParams.set('warehouse', params.warehouse)
searchParams.set('min_stock', String(params.minStock))
if (params.updatedAfter) searchParams.set('updated_after', params.updatedAfter.toISOString())
const url = `https://inventory.internal/api/items?${searchParams}`
const res = await fetch(url, {
headers: {
'Authorization': `Bearer ${process.env.INVENTORY_API_KEY}`,
'Accept': 'application/json',
},
})
if (!res.ok) {
throw new Error(`Inventory API ${res.status}: ${await res.text()}`)
}
return res.json()
}
const results = await searchInventory({
warehouse: 'eu-west-1',
minStock: 10,
updatedAfter: new Date('2025-01-01'),
})
console.log(`Found ${results.total} items`)Requisição POST — codificando o corpo de um formulário em URL
// application/x-www-form-urlencoded POST — used by OAuth token endpoints,
// legacy form-submission APIs, and some webhook providers
async function requestOAuthToken(
clientId: string,
clientSecret: string,
code: string,
redirectUri: string,
): Promise<{ access_token: string; expires_in: number }> {
const body = new URLSearchParams({
grant_type: 'authorization_code',
client_id: clientId,
client_secret: clientSecret,
code,
redirect_uri: redirectUri, // URLSearchParams encodes this automatically
})
const res = await fetch('https://oauth.provider.com/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body.toString(),
// body: body — also works directly in modern environments (Fetch spec accepts URLSearchParams)
})
if (!res.ok) {
const err = await res.json()
throw new Error(`OAuth error: ${err.error_description ?? err.error}`)
}
return res.json()
}Quando precisar testar ou depurar uma URL codificada sem configurar um script, cole o valor bruto diretamente no Codificador de URL — ele codifica e decodifica instantaneamente, mostrando exatamente o que o navegador e o servidor verão. Útil para inspecionar URIs de redirecionamento OAuth, URLs de callback de webhooks e parâmetros de requisições assinadas de CDN.
Codificação de URL pela linha de comando com Node.js e Shell
Para scripts de shell, pipelines de CI, ou depuração rápida, várias abordagens de linha de comando funcionam sem escrever um script completo.
# ── Node.js one-liners — cross-platform (macOS, Linux, Windows) ────────
# encodeURIComponent — encode a single value
node -e "console.log(encodeURIComponent(process.argv[1]))" "Wireless Keyboard & Mouse"
# Wireless%20Keyboard%20%26%20Mouse
# Build a complete query string
node -e "console.log(new URLSearchParams(JSON.parse(process.argv[1])).toString())" '{"q":"standing desk","category":"office-furniture","page":"1"}'
# q=standing+desk&category=office-furniture&page=1
# Decode a percent-encoded string
node -e "console.log(decodeURIComponent(process.argv[1]))" "Wireless%20Keyboard%20%26%20Mouse"
# Wireless Keyboard & Mouse
# ── curl — automatic encoding ───────────────────────────────────────────
# curl --data-urlencode encodes values automatically in GET and POST
curl -G "https://api.example.com/search" --data-urlencode "q=Wireless Keyboard & Mouse" --data-urlencode "category=office furniture"
# ── Python one-liner (available on most systems) ─────────────────────────
python3 -c "from urllib.parse import quote; print(quote(input(), safe=''))"
# (type the string and press Enter)
# ── jq + bash: encode every value in a JSON object ───────────────────────
echo '{"q":"hello world","tag":"node & express"}' | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(new URLSearchParams(d).toString())"
# q=hello+world&tag=node+%26+expressAlternativa de alto desempenho: qs
O URLSearchParams nativo não suporta objetos aninhados ou arrays — a forma de query strings usada por muitas APIs e frameworks. A biblioteca qs (mais de 30M de downloads semanais no npm) lida com toda a gama de padrões de query strings usados na prática: objetos aninhados com notação de colchetes (filters[status]=active), chaves repetidas, codificadores personalizados e formatos de serialização de arrays configuráveis.
npm install qs # or pnpm add qs
import qs from 'qs'
// URLSearchParams cannot represent this structure natively
const reportFilters = {
dateRange: {
from: '2025-01-01',
to: '2025-03-31',
},
status: ['published', 'archived'],
author: { id: 'usr_4f2a9c1b', role: 'editor' },
workspace: 'ws-platform-eu',
}
// qs produces bracket-notation query strings used by Express, Rails, Django REST
const query = qs.stringify(reportFilters, { encode: true })
console.log(query)
// dateRange%5Bfrom%5D=2025-01-01&dateRange%5Bto%5D=2025-03-31&status%5B0%5D=published&status%5B1%5D=archived&author%5Bid%5D=usr_4f2a9c1b&author%5Brole%5D=editor&workspace=ws-platform-eu
// Human-readable (no encoding) — useful for debugging
console.log(qs.stringify(reportFilters, { encode: false }))
// dateRange[from]=2025-01-01&dateRange[to]=2025-03-31&status[0]=published&status[1]=archived...
// Parsing back
const parsed = qs.parse(query)
console.log(parsed.dateRange) // { from: '2025-01-01', to: '2025-03-31' }
console.log(parsed.status) // ['published', 'archived']Para parâmetros simples de chave-valor, URLSearchParams é sempre a escolha certa — é nativo, tem custo zero e é universalmente suportado. Recorra ao qs apenas quando precisar de estruturas aninhadas, formatos de serialização de arrays diferentes de chaves repetidas, ou quando estiver integrando com um framework de back-end que espera query strings em notação de colchetes.
Erros comuns
Já vi esses quatro erros repetidamente em bases de código de produção — a maioria são falhas silenciosas que só surgem quando um valor contém um caractere especial, que é exatamente o tipo de bug que passa despercebido nos testes unitários e só aparece com dados reais de usuários.
Erro 1 — Usar encodeURI() para valores de parâmetros de query
Problema: encodeURI() não codifica &, = nem +. Quando um valor contém esses caracteres, eles são interpretados como sintaxe de query string, dividindo ou sobrescrevendo parâmetros silenciosamente. Solução: use sempre encodeURIComponent() para valores individuais.
// ❌ encodeURI does not encode & and = in the value
// "plan=pro&promo=SAVE20" is treated as two separate params
const planName = 'Pro Plan (save=20% & free trial)'
const url = `/checkout?plan=${encodeURI(planName)}`
// /checkout?plan=Pro%20Plan%20(save=20%%20&%20free%20trial)
// ↑ & breaks the query string// ✅ encodeURIComponent encodes & and = safely
const planName = 'Pro Plan (save=20% & free trial)'
const url = `/checkout?plan=${encodeURIComponent(planName)}`
// /checkout?plan=Pro%20Plan%20(save%3D20%25%20%26%20free%20trial)
// ↑ = and & are both encodedErro 2 — Dupla codificação de uma string já codificada
Problema: Chamar encodeURIComponent() em um valor que já está codificado em porcentagem transforma o % em %25, então %20 vira %2520. O servidor decodifica uma vez e recebe um literal %20 em vez de um espaço. Solução: decodifique primeiro e recodifique, ou garanta que o valor nunca seja codificado duas vezes.
// ❌ encodedParam already contains %20 — encoding again produces %2520
const encodedParam = 'Berlin%20Office'
const url = `/api/locations/${encodeURIComponent(encodedParam)}`
// /api/locations/Berlin%2520Office
// Server sees: "Berlin%20Office" (a literal percent-twenty, not a space)// ✅ Decode first if the value may already be encoded
const maybeEncoded = 'Berlin%20Office'
const clean = decodeURIComponent(maybeEncoded) // 'Berlin Office'
const url = `/api/locations/${encodeURIComponent(clean)}`
// /api/locations/Berlin%20Office — correctErro 3 — Não considerar a diferença entre + / %20 do URLSearchParams e encodeURIComponent
Problema: URLSearchParams codifica espaços como + (application/x-www-form-urlencoded), enquanto encodeURIComponent() usa %20. Misturar ambos na mesma URL — por exemplo, acrescentar uma string pré-codificada a uma saída de URLSearchParams — produz uma codificação inconsistente que confunde alguns parsers. Solução: escolha uma abordagem e use-a de forma consistente em toda a função de construção de URL.
// ❌ Mixed: URLSearchParams uses + for spaces, but we're appending
// a manually-encoded segment that uses %20
const base = new URLSearchParams({ category: 'office furniture' })
const extra = `sort=${encodeURIComponent('price asc')}`
const url = `/api/products?${base}&${extra}`
// /api/products?category=office+furniture&sort=price%20asc
// ↑ two different space encodings in the same URL// ✅ Use URLSearchParams exclusively — consistent encoding throughout
const params = new URLSearchParams({
category: 'office furniture',
sort: 'price asc',
})
const url = `/api/products?${params}`
// /api/products?category=office+furniture&sort=price+ascErro 4 — Esquecer de codificar segmentos de caminho que contêm barras
Problema: Um identificador de recurso como um caminho de arquivo (reports/2025/q1.pdf) usado como segmento de caminho REST contém caracteres / que o roteador do servidor interpreta como separadores de caminho, roteando para um endpoint inexistente. Solução: use sempre encodeURIComponent() para segmentos de caminho que podem conter barras.
// ❌ The file path contains / — the server receives a 3-segment path
// instead of a single resource ID
const filePath = 'reports/2025/q1-financials.pdf'
const url = `https://storage.example.com/objects/${filePath}`
// https://storage.example.com/objects/reports/2025/q1-financials.pdf
// → Server routes to /objects/:year/:filename — 404 or wrong resource// ✅ encodeURIComponent encodes / as %2F — single path segment
const filePath = 'reports/2025/q1-financials.pdf'
const url = `https://storage.example.com/objects/${encodeURIComponent(filePath)}`
// https://storage.example.com/objects/reports%2F2025%2Fq1-financials.pdf
// → Server receives the full file path as one resource identifierMétodos de codificação de URL em JavaScript — Comparação rápida
| Método | Codifica espaços como | Codifica & = ? | Codifica # / : | Caso de uso | Requer instalação |
|---|---|---|---|---|---|
| encodeURIComponent() | %20 | ✅ sim | ✅ sim | Codificar valores de parâmetros individuais | No |
| encodeURI() | %20 | ❌ não | ❌ não | Sanear uma string de URL completa | No |
| URLSearchParams | + | ✅ sim | ✅ sim | Construir e analisar query strings | No |
| Construtor URL | auto por componente | auto | auto | Construir e normalizar URLs completas | No |
| biblioteca qs | %20 (configurável) | ✅ sim | ✅ sim | Objetos aninhados e arrays em query strings | npm install qs |
Para a grande maioria dos casos, a escolha se resume a três cenários. Use URLSearchParams ao construir query strings com múltiplos parâmetros a partir de dados estruturados — é a opção mais segura e legível. Use encodeURIComponent() para codificar um único valor em uma URL com template literal, para segmentos de caminho, ou para valores em sistemas que esperam %20 em vez de + para espaços (como as URLs assinadas do AWS S3). Recorra ao qs apenas quando sua query string carregar objetos aninhados ou arrays que URLSearchParams não consegue representar nativamente.
Perguntas frequentes
Ferramentas relacionadas
Para codificar ou decodificar com um clique sem escrever nenhum código, cole sua string diretamente no Codificador de URL — ele lida com a codificação percentual e decodificação instantaneamente no seu navegador, com a saída codificada pronta para copiar em uma chamada fetch ou no terminal.
Alex is a front-end and Node.js developer with extensive experience building web applications and developer tooling. He is passionate about web standards, browser APIs, and the JavaScript ecosystem. In his spare time he contributes to open-source projects and writes about modern JavaScript patterns, performance optimisation, and everything related to the web platform.
Sophie is a full-stack developer focused on TypeScript across the entire stack — from React frontends to Express and Fastify backends. She has a particular interest in type-safe API design, runtime validation, and the patterns that make large JavaScript codebases stay manageable. She writes about TypeScript idioms, Node.js internals, and the ever-evolving JavaScript module ecosystem.