URL, кодирующий пробел: + или% 20? - PullRequest
649 голосов
/ 28 октября 2009

Когда в URL-адресе указан пробел +, а в %20? * *

Ответы [ 4 ]

381 голосов
/ 28 октября 2009

С Википедия (выделение и ссылка добавлены):

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

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

252 голосов
/ 29 апреля 2015

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

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

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

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

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

"https://bob:bobby@www.lunatech.com:8080/file;p=1?q=2#third"

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

+-------------------+---------------------+
|        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:bobby@www.lunatech.com:8080/file;p=1?q=2#third
\___/   \_/ \___/ \______________/ \__/\_______/ \_/ \___/
  |      |    |          |          |      | \_/  |    |
Scheme User Password    Host       Port  Path |   | Fragment
        \_____________________________/       | Query
                       |               Path parameter
                   Authority

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

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

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

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

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

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

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

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

Источник

22 голосов
/ 28 октября 2009

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

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

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

EDIT:

Кажется, я ошибаюсь. urlencode() в Python (по крайней мере, в 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+'
11 голосов
/ 27 октября 2016

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

По моему мнению, лучше всегда кодировать пробелы как% 20, а не как "+", даже в части запроса URL, потому что это спецификация HTML (RFC-1866), которая указывает, что пробелы должны быть кодируется как "+" в парах "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". Таким образом, только после"? ", Пробелы можно заменить на плюсы . В других в некоторых случаях пробелы должны быть закодированы в% 20. Но так как трудно правильно определить контекст, лучше никогда не кодировать пробелы как "+".

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...