URL que codifica o caractere de espaço: + ou% 20?

723

Quando é codificado um espaço em um URL +e quando é codificado %20?

BC.
fonte
2
Essa pergunta seria mais útil, pois várias perguntas específicas ao idioma, certo?
squarecandy
2
Possível duplicata de Quando codificar espaço para mais (+) ou% 20?
usuário
3
@ usuário a pergunta que você vincular foi feita mais tarde, tornando-a burra, não esta.
Chimpanzé em guerra

Respostas:

425

Da Wikipedia (ênfase e link adicionados):

Quando os dados inseridos nos formulários HTML são enviados, os nomes e valores dos campos do formulário são codificados e enviados ao servidor em uma mensagem de solicitação HTTP usando o método GET ou POST ou, historicamente, por email. A codificação usada por padrão é baseada em uma versão muito antiga das regras gerais de codificação de porcentagem de URI, com várias modificações , como normalização de nova linha e substituição de espaços por "+" em vez de "% 20". O tipo de dado MIME codificado dessa maneira é application / x-www-form-urlencoded e atualmente está definido (ainda de maneira muito desatualizada) nas especificações HTML e XForms.

Portanto, a porcentagem real de codificação usa %20enquanto os dados do formulário nos URLs estão em um formulário modificado que usa +. Portanto, é mais provável que você veja apenas os +URLs na string de consulta após um ?.

Joey
fonte
2
Então, a codificação + seria tecnicamente multipart / codificação de dados de formulário, enquanto a codificação percentual é codificada por application / x-www-form-url?
BC.
17
@BC: no - multipart/form-datausa codificação MIME; application/x-www-form-urlencodedusa +e usa URIs codificados corretamente %20.
27409 McDowell
8
"Então é mais provável que você só veja + nos URLs na string de consulta depois de um?" É um eufemismo. Você nunca deve ver "+" na parte do caminho da URL, pois ela não fará o que você espera (espaço).
Adam Gent
34
Então, basicamente: Alvo de submissão GET é http://www.bing.com/search?q=hello+worlde um recurso com espaço no nomehttp://camera.phor.net/cameralife/folders/2012/2012-06%20Pool%20party/
William Entriken
8
Observe que, para links de email, você precisa de% 20 e não + após o?. Por exemplo mailto:[email protected]?subject=I%20need%20help,. Se você tentou isso com +, o email será aberto com + es em vez de espaços.
Sygmoral
288

Essa confusão ocorre porque os URLs ainda estão "quebrados" até hoje.

Veja " http://www.google.com ", por exemplo. Este é um URL. Uma URL é um Localizador Uniforme de Recursos e é realmente um ponteiro para uma página da Web (na maioria dos casos). Os URLs realmente têm uma estrutura muito bem definida desde a primeira especificação em 1994.

Podemos extrair informações detalhadas sobre o URL " http://www.google.com ":

+---------------+-------------------+
|      Part     |      Data         |
+---------------+-------------------+
|  Scheme       | http              |
|  Host         | www.google.com    |
+---------------+-------------------+

Se olharmos para um URL mais complexo, como:

" https: // bob: [email protected]: 8080 / arquivo; p = 1? q = 2 # terceiro "

podemos extrair as seguintes informações:

+-------------------+---------------------+
|        Part       |       Data          |
+-------------------+---------------------+
|  Scheme           | https               |
|  User             | bob                 |
|  Password         | bobby               |
|  Host             | www.lunatech.com    |
|  Port             | 8080                |
|  Path             | /file;p=1           |
|  Path parameter   | p=1                 |
|  Query            | q=2                 |
|  Fragment         | third               |
+-------------------+---------------------+

https://bob:[email protected]:8080/file;p=1?q=2#third
\___/   \_/ \___/ \______________/ \__/\_______/ \_/ \___/
  |      |    |          |          |      | \_/  |    |
Scheme User Password    Host       Port  Path |   | Fragment
        \_____________________________/       | Query
                       |               Path parameter
                   Authority

Os caracteres reservados são diferentes para cada parte.

Para URLs HTTP, um espaço em uma parte do fragmento do caminho deve ser codificado para "% 20" (não, absolutamente não "+"), enquanto o caractere "+" na parte do fragmento do caminho pode ser deixado sem codificação.

Agora, na parte da consulta, os espaços podem ser codificados para "+" (para compatibilidade com versões anteriores: não tente procurá-lo no padrão URI) ou "% 20" enquanto o caractere "+" (como resultado dessa ambiguidade) ) deve ser escapado para "% 2B".

Isso significa que a string "azul + azul claro" deve ser codificada de maneira diferente nas partes do caminho e da consulta:

" http://example.com/blue+light%20blue?blue%2Blight+blue ".

A partir daí, você pode deduzir que a codificação de um URL totalmente construído é impossível sem um conhecimento sintático da estrutura do URL.

Isso se resume a:

Você deve ter %20antes ?e +depois.

Fonte

Matas Vaitkevicius
fonte
>> você deve ter% 20 antes da? e + depois Desculpe pela pergunta boba. Eu sei um pouco de alguma forma que o parâmetro hashtag é usado depois de "?" parâmetro de ponto de interrogação. Embora seja de alguma forma diferente porque usar "#" não recarrega a página. Mas eu tenho tentado usar o sinal% 20 e + após a hashtag "#" e parece não estar funcionando. Qual deles precisa ser usado depois de "#"?
Philcyb
@Philcyb Você pode querer ler isso en.wikipedia.org/wiki/Percent-encoding
Matas Vaitkevicius
A parte da consulta realmente possui um padrão "oficial"? Eu pensei que basicamente essa parte é específica da aplicação. 99,99% dos aplicativos usam key1=value1&key1=value2onde chaves e valores são codificados com as regras a encodeURIComponentseguir, mas AFAIK o conteúdo da parte da consulta é totalmente 100% superior ao aplicativo. Caso contrário, ele só vai para o primeiro, #não há codificação oficial.
gman
Uma resposta duplicada para a pergunta duplicada! Mas hmm, ok, desisti de ambos.
Vladimir Vukanac
3
Essa rotulagem de componente ASCII é épica.
jsejcksn
25

Eu recomendaria %20.

Você está codificando-os?

Isso não é muito consistente entre os idiomas. Se não me engano, no PHP urlencode()trata os espaços como se o +Python os urlencode()tratasse como %20.

EDITAR:

Parece que estou enganado. O Python urlencode()(pelo menos no 2.7.2) usa em quote_plus()vez de quote()e, portanto, codifica os espaços como "+". Parece também que a recomendação do W3C é o "+" conforme aqui: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

De fato, você pode acompanhar este interessante debate no rastreador de problemas do Python sobre o que usar para codificar espaços: http://bugs.python.org/issue13866 .

EDIT # 2:

Entendo que a maneira mais comum de codificar "" é como "+", mas apenas uma observação, pode ser apenas eu, mas acho isso um pouco confuso:

import urllib
print(urllib.urlencode({' ' : '+ '})

>>> '+=%2B+'
Rui Vieira
fonte
Não codificado. Tentando determinar, de uma perspectiva estética, como serão os meus URLs que contêm espaços.
BC.
Oi, também estou confuso, quando o usuário envia o formulário html, como o formulário codifica o espaço? com qual personagem? O resultado depende do navegador?
GMsoF 7/11/12
1
E o URLEncoder.encode()método em Java também o converte +.
24414
E então surge a questão de como tratar a codificação no corpo de uma solicitação POST: "Tipo de conteúdo: application / x-www-form-urlencoded", em que os parâmetros estão na forma de "a = b & c = d", mas não estão em um URL, apenas no corpo do "documento". Eles fizeram uma bagunça real com esse problema, e é difícil encontrar respostas definitivas.
Fyngyrz
Perls uri_escape () trata-los como% 20
someuser
16

Um espaço só pode ser codificado para "+" nos pares de valor-chave do tipo de conteúdo "application / x-www-form-urlencoded" consulta parte de um URL. Na minha opinião, este é um maio, não uma obrigação. No restante dos URLs, ele é codificado como% 20.

Na minha opinião, é melhor sempre codificar espaços como% 20, não como "+", mesmo na parte da consulta de uma URL, porque é a especificação HTML (RFC-1866) que especifica que os caracteres de espaço devem ser codificados como " + pares de valor-chave de tipo de conteúdo de aplicativo "in" / x-www-form-urlencoded "(consulte o parágrafo 8.2.1, parágrafo 1.)

Essa maneira de codificar os dados do formulário também é fornecida em especificações HTML posteriores. Por exemplo, procure parágrafos relevantes sobre application / x-www-form-urlencoded na especificação HTML 4.01 e assim por diante.

Aqui está um exemplo de string no URL em que a especificação HTML permite a codificação de 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 . Em outros casos, os espaços devem ser codificados para% 20. Mas como é difícil determinar corretamente 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 / "-" / "." / "_" / "~"

A implementação depende da linguagem de programação que você escolheu.

Se o seu URL contiver caracteres nacionais, primeiro codifique-os para UTF-8 e depois codifique por cento o resultado.

Maxim Masiutin
fonte
1
Por que alguém deveria se importar com a especificação HTML se o recurso solicitado não é HTML? Eu já vi "+" em algumas APIs da Web que não respondem com HTML, por exemplo, você solicita um pdf. Considero errado que eles não usem "% 20".
A incrível Jan
@TheincredibleJan, eu concordo com você. É disso que trata minha resposta.
Maxim Masiutin
1
@MaximMasiutin Quando sua resposta diz "Este é um MAIO, não um DEVER", a que especificação você está se referindo? Estou lutando para encontrar uma especificação que a possua como um de maio. Em w3.org/TR/1999/REC-html401-19991224/interact/…, o uso de '+' (na seção de consulta) está dentro de uma seção 'must' da especificação.
JosephH 7/05/19
2
@ JosephphH - obrigado pela sua nota. É minha opinião persional sobre MAIO. Eu editei a postagem. O que eu quis dizer é que a especificação HTML que você define define "+", mas no contexto da URL, outras regras se aplicam, que também permitem espaços de codificação como% 20.
Maxim Masiutin