web-dev-qa-db-pt.com

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

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

641
BC.

De Wikipedia (ênfase e link adicionado):

Quando dados inseridos em formulários HTML são enviados, os nomes e valores dos campos de 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 inicial das regras gerais de codificação de percentual de URI, com um número de modificações como normalização de nova linha e substituição de espaços por "+" em vez de "% 20" . O tipo MIME de dados codificados desta forma é application/x-www-form-urlencoded, e atualmente é definido (ainda de maneira muito desatualizada) nas especificações HTML e XForms.

Portanto, a codificação real percent usa %20 enquanto os dados de formulário em URLs estão em um formato modificado que usa +. Então você provavelmente só verá + em URLs na string de consulta depois de um ?.

378
Joey

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

Tome " http://www.google.com " por exemplo. Este é um URL. Um URL é um localizador de recursos uniforme e é realmente um ponteiro para uma página da Web (na maioria dos casos). Na verdade, as URLs 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/file; 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 de fragmento de caminho tem que ser codificado para "% 20" (não, absolutamente não "+"), enquanto o caractere "+" na parte de fragmento de caminho pode ser deixado sem codificação.

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

Isso significa que a string "blue + light blue" deve ser codificada de forma diferente nas partes path e query:

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

A partir daí, você pode deduzir que a codificação de uma URL totalmente construída é impossível sem uma percepção sintática da estrutura da URL.

Isso se resume a:

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

Fonte

246
Matas Vaitkevicius

Eu recomendaria %20.

Você está codificando-os?

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

EDITAR:

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

E, de fato, você pode acompanhar esse debate interessante sobre o próprio rastreador de problemas do Python sobre o que usar para codificar espaços: http://bugs.python.org/issue13866 .

EDIT # 2:

Eu entendo que a maneira mais comum de codificar "" é como "+", mas apenas uma nota, pode ser apenas eu, mas acho isso um pouco confuso:

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

>>> '+=%2B+'
21
Rui Vieira

Um espaço só pode ser codificado para "+" na parte de consulta de pares de valor-chave do tipo de conteúdo "application/x-www-form-urlencoded" de um URL. Este é um maio, não é necessário. 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 de consulta de uma URL, porque é a especificação HTML (RFC-1866) que especificou que os caracteres de espaço devem ser codificados como " + "em" application/x-www-form-urlencoded "pares de valores-chave do tipo de conteúdo. (ver ponto 8.2.1, primeiro parágrafo)

Essa maneira de codificar dados de formulários também é fornecida em especificações HTML posteriores. Por exemplo, procure parágrafos relevantes sobre application/x-www-form-url codificado em HTML 4.01 Specification e assim por diante.

Aqui está uma string de amostra na URL onde a especificação HTML permite espaços de codificação como vantagens: " http://example.com/over/there?name=foo+bar ". Então, somente depois de "?", Espaços podem ser substituídos por vantagens, de acordo com a especificação HTML. 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 para codificar por cento todos os caracteres, exceto "sem reservas" definidos no RFC-3986, p.2.3

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"

A implementação depende da linguagem de programação escolhida.

Se o seu URL contiver caracteres nacionais, primeiro codifique-os para UTF-8 e, em seguida, codifique por porcentagem o resultado.

10
Maxim Masiutin