Codificação de Espaços em URL: %20 vs + (Quando Usar Cada Um)
%20 é a codificação percentual padrão do RFC 3986 para o caractere de espaço e deve ser usada em caminhos de URL e na maioria dos contextos. O sinal + representa um espaço apenas no formato application/x-www-form-urlencoded, usado em envios de formulários HTML e em algumas query strings.
O Que Significa %20?
%20 é a representação em codificação percentual do caractere de espaço (código ASCII 32, hexadecimal 0x20), conforme definido pelo RFC 3986. É a forma padrão de representar espaços em qualquer parte de um URI, incluindo segmentos de caminho, query strings e identificadores de fragmento.
Quando você vê %20 em uma URL, isso simplesmente significa "há um espaço aqui". Por exemplo, https://example.com/my%20file.pdf refere-se a um recurso chamado "my file.pdf". O %20 é universalmente compreendido por todos os servidores web, navegadores e bibliotecas HTTP.
O Que Significa + em uma URL?
O sinal + representando um espaço tem origem no tipo de conteúdo application/x-www-form-urlencoded, que foi definido na especificação HTML para codificar dados de formulário. Quando um formulário HTML é enviado usando o método GET, o navegador codifica os espaços como + na query string resultante.
Por exemplo, se você digitar "hello world" em um formulário de pesquisa e enviá-lo, o navegador gera uma URL como https://example.com/search?q=hello+world. O + aqui significa "espaço", mas apenas porque a query string está usando o formato form-urlencoded.
É importante observar que o + não tem significado especial fora do formato application/x-www-form-urlencoded. Em um caminho de URL como /files/my+file.pdf, o + é um sinal de mais literal, não um espaço. O arquivo referenciado chama-se literalmente "my+file.pdf".
A Diferença Fundamental
A diferença fundamental está na especificação a que cada um pertence. %20 é definido pelo RFC 3986 (URIs) e funciona em qualquer lugar de uma URL. A convenção do +-como-espaço é definida pela especificação HTML/WHATWG para dados de formulário e só funciona em query strings que são explicitamente tratadas como dados form-urlencoded.
%20funciona em caminhos, query strings, fragmentos e todos os contextos de URI+só significa "espaço" em query stringsapplication/x-www-form-urlencoded- Em caminhos de URL,
+é um sinal de mais literal, não um espaço %20é sempre seguro;+depende do contexto- Se você codificar um
+literal em dados de formulário, ele se torna%2B
Qual Você Deve Usar?
Use %20 ao construir URLs programaticamente, montar requisições de API REST, codificar segmentos de caminho ou sempre que estiver em dúvida. É a codificação universalmente correta para espaços em URIs.
Use + apenas quando estiver intencionalmente produzindo dados application/x-www-form-urlencoded, como ao montar query strings que imitam envios de formulários HTML, ou quando uma API exigir explicitamente esse formato.
A maioria das APIs e frameworks modernos aceita tanto %20 quanto + em query strings. No entanto, usar %20 é mais portável e evita ambiguidades, especialmente quando a query string pode ser usada em contextos fora de envios de formulário.
Como Diferentes Linguagens Lidam com Espaços
Diferentes linguagens de programação e suas bibliotecas padrão podem usar %20 ou + por padrão para codificar espaços. Conhecer o comportamento padrão da sua linguagem ajuda a evitar surpresas.
// JavaScript
encodeURIComponent('hello world'); // "hello%20world" (%20)
new URLSearchParams({q: 'hello world'}).toString(); // "q=hello+world" (+)
// Para forçar %20 em query strings:
new URLSearchParams({q: 'hello world'}).toString().replace(/\+/g, '%20');
# Python
from urllib.parse import quote, quote_plus, urlencode
quote('hello world', safe='') # "hello%20world" (%20)
quote_plus('hello world') # "hello+world" (+)
urlencode({'q': 'hello world'}) # "q=hello+world" (+ por padrão)
# Para forçar %20:
urlencode({'q': 'hello world'}, quote_via=quote) # "q=hello%20world"
// PHP
rawurlencode('hello world'); // "hello%20world" (%20)
urlencode('hello world'); // "hello+world" (+)
// rawurlencode segue o RFC 3986
// urlencode segue application/x-www-form-urlencoded