Quando codificar espaço para mais (+) ou% 20?

Respostas:

481

+significa um espaço apenas no application/x-www-form-urlencodedconteúdo, como a parte da consulta de um URL:

http://www.example.com/path/foo+bar/path?query+name=query+value

Nesta URL, o nome do parâmetro está query namecom um espaço e o valor está query valuecom um espaço, mas o nome da pasta no caminho está literalmente foo+bar, não foo bar .

%20é uma maneira válida de codificar um espaço em qualquer um desses contextos. Portanto, se você precisar codificar por URL uma sequência para inclusão em parte de uma URL, é sempre seguro substituir espaços por %20e acrescentar por %2B. Isto é o que, por exemplo. encodeURIComponent()faz em JavaScript. Infelizmente, não é o que o urlencode faz no PHP ( rawurlencode é mais seguro).

Consulte também HTML 4.01 application / x-www-form-urlencoded

bobince
fonte
5
realmente estou confuso, minha pergunta é: quando o navegador faz a primeira forma e quando o segundo fomr?
Muhammad Hewedy
11
O navegador criará um query+name=query+valueparâmetro a partir de um formulário com <input name="query name" value="query value">. Ele não será criado a query%20namepartir de um formulário, mas é totalmente seguro usá-lo, por exemplo. se você estiver juntando um envio de formulário para um XMLHttpRequest. Se você tiver um URL com um espaço <a href="http://www.example.com/foo bar/">, o navegador o codificará para que %20você corrija seu erro, mas provavelmente é melhor não confiar nele .
bobince
6
que função em make javascript foo barpara foo+bar?
Sisir
21
@ Sisir: não existe uma função JS que faça codificação de formulário de URL. Você pode, naturalmente, fazer encodeURIComponent(s).replace(/%20/g, '+')se você realmente precisa+
bobince
2
Esse é um exemplo muito, muito confuso de algo codificado em forma de URL. Não tem nada a ver com URLs.
Dave Van den Eynde
54

http://www.example.com/some/path/to/resource?param1=value1

A parte antes do ponto de interrogação deve usar% de codificação (portanto, %20para espaço), após o ponto de interrogação você pode usar um %20ou +para um espaço. Se você precisar de um valor real +após o ponto de interrogação, use %2B.

cerberos
fonte
6
@DaveVandenEynde Por que não?
Cerberos
10
porque está errado. Faz parte do tipo de mídia antigo application / x-www-form-urlencoded que não se aplica a URLs. Além disso, decodeURIComponentnão decodifica.
Dave Van den Eynde
3
Sim, provavelmente foi copiado da RFC 1630 e nunca foi realmente um padrão. tools.ietf.org/html/rfc3986 é o padrão (atualizado novamente para IPv6 ou algo assim). Certamente os navegadores ainda "suportam", mas o que isso significa? É o código do servidor ou do cliente que lê a string de consulta e a decodifica, não o navegador. O navegador simplesmente o passa para frente e para trás e, como +é um caractere reservado, ele será preservado.
Dave Van den Eynde
18
O Google usa + para espaços nos URLs de pesquisa ( google.com/#q=perl+equivalent+to+php+urlencode+spaces+as+%2B ).
23614 Justin justin
2
FYI: Rails também decodifica espaços com +por padrão ( { foo: 'bar bar'}.to_query=> foo=bar+bar)
wrtsprt
46

Portanto, as respostas aqui são um pouco incompletas. O uso de um '% 20' para codificar um espaço em URLs é explicitamente definido no RFC3986 , que define como um URI é criado. Não há menção nesta especificação de usar um '+' para codificar espaços - se você seguir apenas essa especificação, um espaço deverá ser codificado como '% 20'.

A menção de usar '+' para codificar espaços vem de várias encarnações da especificação HTML - especificamente na seção que descreve o tipo de conteúdo 'application / x-www-form-urlencoded'. Isso é usado para postar dados do formulário.

Agora, a Especificação HTML 2.0 (RFC1866) disse explicitamente, na seção 8.2.2, que a parte Query da string de URL de uma solicitação GET deve ser codificada como 'application / x-www-form-urlencoded'. Em teoria, isso sugere que é legal usar um '+' no URL na string de consulta (depois do '?').

Mas ... é mesmo? Lembre-se, o próprio HTML é uma especificação de conteúdo e os URLs com cadeias de consulta podem ser usados ​​com outro conteúdo que não o HTML. Além disso, enquanto as versões posteriores da especificação HTML continuam a definir '+' como legal no conteúdo 'application / x-www-form-urlencoded', elas omitem completamente a parte dizendo que as seqüências de consulta de solicitação GET são definidas como esse tipo. De fato, não há nenhuma menção sobre a codificação da string de consulta em nada após a especificação do HTML 2.0.

O que nos deixa com a pergunta - é válida? Certamente, existe MUITO código legado que suporta '+' nas strings de consulta e muito código que o gera também. Portanto, as probabilidades são boas, você não quebrará se usar '+'. (E, de fato, fiz toda a pesquisa sobre isso recentemente porque descobri um site importante que falhou em aceitar '% 20' em uma consulta GET como um espaço. Na verdade, eles não conseguiram decodificar QUALQUER caractere codificado por cento. Portanto, o serviço que você também pode ser relevante.)

Mas a partir de uma leitura pura das especificações, sem que o idioma da especificação HTML 2.0 seja transferido para versões posteriores, os URLs são cobertos inteiramente pelo RFC3986, o que significa que os espaços devem ser convertidos para '% 20'. E definitivamente esse deve ser o caso se você estiver solicitando algo diferente de um documento HTML.

zgwortz
fonte
Para adicionar à sua resposta, o Chrome, por padrão, codifica espaços nos URLs como %20( <a href="?q=a b">), mas quando você envia um formulário, ele usa o +sinal. Você pode substituir isso usando explicitamente o +sinal ( <a href="?q=a+b">) ou enviando o formulário usando XMLHTTPRequest.
X-yuri
É realmente difícil entender o objetivo de adicionar URLSearchParams developers.google.com/web/updates/2016/01/urlsearchparams , que funciona de alguma maneira herdada (serialize SPACE em '+'). Ele ainda não é suportado no IE11!
Ninfetamina
9

É melhor sempre codificar espaços como% 20, não como "+".

Foi o RFC-1866 (especificação HTML 2.0), que especificou que os caracteres de espaço devem ser codificados como "+" em "pares de valor-chave do tipo de conteúdo application / x-www-form-urlencoded". (ver ponto 8.2.1, primeiro parágrafo). Essa maneira de codificar dados de formulário também é fornecida em especificações HTML posteriores; procure parágrafos relevantes sobre application / x-www-form-urlencoded.

Aqui está um exemplo de uma string no URL em que o RFC-1866 permite codificar espaços como vantagens: "http://example.com/over/there?name=foo+bar". Portanto, somente após "?", Os espaços podem ser substituídos por vantagens, de acordo com a RFC-1866. Em outros casos, os espaços devem ser codificados para% 20. Mas como é difícil determinar o contexto, é a melhor prática nunca codificar espaços como "+".

Eu recomendaria codificar por cento todos os caracteres, exceto "não reservado", definido na RFC-3986, p.2.3

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
Maxim Masiutin
fonte
1
No .Net Framework, o UrlEncode usa '+' no QueryString, mas no .Net Core moderno% 20 é usado
Michael Freidgeim
@ MiFreidgeimSO-stopbeingevil Obrigado por nos informar. Parece que o .Net Core moderno decidiu ser mais consistente e compatível.
Maxim Masiutin 20/02
2

Qual é a diferença: Veja outras respostas.

Quando usar em +vez de %20? Use +se, por algum motivo, você desejar tornar a string de consulta da URL ( ?.....) ou o fragmento de hash ( #....) mais legível. Exemplo: Você pode realmente ler isto:

https://www.google.se/#q=google+doesn%27t+encode+:+and+uses+%2B+instead+of+spaces ( %2B= +)

Mas é muito mais difícil ler o seguinte: (pelo menos para mim)

https://www.google.se/#q=google%20doesn%27t%20oops%20:%20%20this%20text%20%2B%20is%20different%20spaces

Eu acho que +é improvável que quebre algo, já que o Google usa +(veja o primeiro link acima) e eles provavelmente pensaram sobre isso. Vou me usar +só porque legível + o Google acha que está tudo bem.

KajMagnus
fonte
7
Eu digo que o argumento "legibilidade" é a melhor defesa para '+'. O argumento "google do it" é falacioso en.wikipedia.org/wiki/Argument_from_authority
FlipMcF
2
@FlipMcF A página falaciosa da Wikipedia sobre argumento de autoridade é sobre "quando uma autoridade é citada em um tópico fora de sua área de especialização ou quando a autoridade citada não é um especialista de verdade " - acho, no entanto, que computadores, HTTP e URL codificação é coisa dentro de área de especialização do Google.
KajMagnus
3
@FlipMcF A citação do comportamento do google, neste caso, é um argumento válido para o uso de "+" nos URLs. Não é que o google seja uma autoridade, mas provavelmente é a maior empresa de internet e, se de alguma forma eles fazem algo, é altamente improvável que os navegadores um dia decidam parar de apoiar essa prática. Além disso, o google chrome é um dos navegadores com maior participação e suporta o que o google quiser. Em suma, eu diria que ninguém usando "+" em vez de "% 20" terá dificuldades por causa disso no futuro próximo.
Jdferreira 13/05
Eu adoraria continuar esse argumento em outro lugar, onde exista um apelo à popularidade para recusar um apelo à autoridade. Pelo menos nós todos podemos concordar em uma coisa: '+' é superior a '% 20'
FlipMcF
1
Na verdade, o URL com% 20 é muito mais fácil de ler porque os navegadores (de mesa) mostram o URL decodificado na parte inferior da janela se você mover o cursor do mouse sobre o link. Os sinais de adição são exibidos inalterados.
Martin