URL-код, кодирующий символ пробела: + или %20?

Когда это пробел в URL, закодированном до +, и когда он закодирован до %20?

Ответ 1

Из Wikipedia (выделение и ссылка добавлены):

Когда данные, введенные в формы HTML, отправляются, имена и значения полей формы кодируются и отправляются на сервер в сообщении HTTP-запроса с использованием метода GET или POST или, исторически, по электронной почте. Кодировка, используемая по умолчанию, основана на очень ранней версии общих правил кодирования URI, с количеством модификаций, таких как нормализацию новой строки и замену пробелов на "+" вместо "%20". Тип данных MIME, закодированный таким образом, является application/x-www-form-urlencoded, и в настоящее время он определен (все еще в очень устаревшем способом) в спецификациях HTML и XForms.

Таким образом, реальная процентная кодировка использует %20, тогда как данные формы в URL-адресах находятся в модифицированной форме, которая использует +. Таким образом, вы скорее всего увидите только + в URL-адресах в строке запроса после ?.

Ответ 2

Эта путаница объясняется тем, что URL до сих пор "не работают".

Возьмите, например, http://www.google.com. Это URL. URL-адрес - это унифицированный указатель ресурса и действительно указатель на веб-страницу (в большинстве случаев). URL-адреса на самом деле имеют очень четкую структуру со времени первой спецификации в 1994 году.

Мы можем извлечь подробную информацию об URL-адресе " http://www.google.com ":

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

Если мы посмотрим на более сложный URL, такой как:

" https://bob: [email protected]: 8080/file; p = 1? q = 2 # третий "

мы можем извлечь следующую информацию:

+-------------------+---------------------+
|        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

Зарезервированные символы различны для каждой части.

Для HTTP-URL пробел в части фрагмента пути должен быть закодирован как " %20" (не совсем, не "+"), а символ "+" в части фрагмента пути может быть оставлен незакодированным.

Теперь в части запроса пробелы могут быть закодированы либо в "+" (для обратной совместимости: не пытайтесь искать его в стандарте URI), либо в " %20", пока символ "+" (в результате этой неоднозначности ) должен быть экранирован до "% 2B".

Это означает, что строка "синий + голубой" должна кодироваться по-разному в частях пути и запроса:

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

Отсюда вы можете сделать вывод, что кодирование полностью сконструированного URL невозможно без синтаксического понимания структуры URL.

Это сводится к:

Вы должны иметь %20 до ? и + после.

Источник

Ответ 3

Я бы порекомендовал %20.

Вы жестко их кодируете?

Это не очень согласовано между языками. Если я не ошибаюсь, в PHP urlencode() рассматриваются пробелы как +, тогда как Python urlencode() рассматривает их как %20.

EDIT:

Кажется, я ошибаюсь. Python urlencode() (по крайней мере, в 2.7.2) использует quote_plus() вместо quote() и, следовательно, кодирует пробелы как "+". Похоже, что рекомендация W3C - это "+", как здесь: http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1

И на самом деле вы можете следить за этой интересной дискуссией о собственном выпуске журнала Python о том, что нужно использовать для кодирования пробелов: http://bugs.python.org/issue13866.

ИЗМЕНИТЬ № 2:

Я понимаю, что наиболее распространенный способ кодирования "" - это "+", но просто примечание, это может быть только я, но я нахожу это немного запутанным:

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

>>> '+=%2B+'

Ответ 4

Пробел может быть закодирован только в "+" в части запроса "пары ключ-значение контента" типа application/x-www-form-urlencoded части URL. Это МОЖЕТ, а НЕ ДОЛЖНО. В остальных URL он закодирован как %20.

На мой взгляд, лучше всегда кодировать пробелы как %20, а не как "+", даже в части запроса URL-адреса, поскольку в спецификации HTML (RFC-1866) указано, что пробельные символы должны кодироваться как " + "in" application/x-www-form-urlencoded "пары ключ-значение типа содержимого. (см. пункт 8.2.1. подпункт 1.)

Этот способ кодирования данных формы также приведен в более поздних спецификациях HTML. Например, посмотрите соответствующие параграфы о application/x-www-form-urlencoded в спецификации HTML 4.01 и т.д.

Вот пример строки в URL, где спецификация HTML допускает кодирование пробелов в виде плюсов: " http://example.com/over/there?name=foo+bar ". Таким образом, только после "?", Пробелы могут быть заменены на плюсы, в соответствии со спецификацией HTML. В других случаях пробелы должны быть закодированы в %20. Но так как трудно правильно определить контекст, лучше никогда не кодировать пробелы как "+".

Я бы порекомендовал кодировать в процентах все символы, кроме "незарезервированных", определенных в RFC-3986, п.2.3.

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

Реализация зависит от языка программирования, который вы выбрали.

Если ваш URL содержит национальные символы, сначала закодируйте их в UTF-8, а затем закодируйте в процентах результат.

Ответ 5

Вы можете использовать функции кодирования URL. PHP имеет

rawurlencode() 

функция

ASP имеет

Server.URLEncode() 

функция

В JavaScript вы можете использовать

encodeURIComponent() 

функция.