Когда закодировать пробел до плюс (+) или %20?

Иногда пробелы кодируются URL-адресом в знак +, а иногда - в %20. В чем разница и почему это должно произойти?

Ответ 1

+ означает пробел только в application/x-www-form-urlencoded содержимом, таком как часть запроса URL-адреса:

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

В этом URL-адресе имя параметра query name с пробелом и значением query value с пробелом, но имя папки в пути буквально foo+bar, а не foo bar.

%20 - допустимый способ кодирования пространства в любом из этих контекстов. Поэтому, если вам нужно URL-кодировать строку для включения в часть URL-адреса, всегда можно заменить пробелы с %20 и плюсами с помощью %2B. Это то, что напр. encodeURIComponent() в JavaScript. К сожалению, это не то, что urlencode делает в PHP (rawurlencode безопаснее).

См. также HTML 4.01 Приложение спецификации/x-www-form-urlencoded

Ответ 2

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

Часть перед вопросительным знаком должна использовать% encoding (so %20 для пробела), после вопросительного знака вы можете использовать либо %20, либо + для пробела. Если вам нужен фактический + после использования вопросительного знака %2B.

Ответ 3

Итак, ответы здесь немного неполны. Использование "%20" для кодирования пространства в URL-адресах явно определено в RFC3986, которое определяет, как создается URI. В этой спецификации не упоминается использование "+" для пространств кодирования - если вы идете исключительно по этой спецификации, пространство должно быть закодировано как "%20".

Упоминание об использовании "+" для пространств кодирования исходит из различных воплощений спецификации HTML - особенно в разделе, описывающем тип контента "application/x-www-form-urlencoded" . Это используется для публикации данных формы.

Теперь спецификация HTML 2.0 (RFC1866) явно указала в разделе 8.2.2, что часть запроса строки URL-адреса запроса GET должен быть закодирован как "application/x-www-form-urlencoded" . Это, теоретически, предполагает, что право на использование "+" в URL-адресе в строке запроса (после "?" ).

Но... это правда? Помните, что HTML сам по себе является спецификацией содержимого, а URL-адреса с строками запросов могут использоваться с контентом, отличным от HTML. Далее, в то время как более поздние версии спецификации HTML продолжают определять "+" как законные в содержании "application/x-www-form-urlencoded" , они полностью опускают часть, говорящую, что строки запроса запроса GET определены как этот тип. Фактически нет никакого упоминания о кодировке строки запроса в чем-либо после спецификации HTML 2.0.

Что оставляет нас с вопросом - действительно ли это? Конечно, есть много устаревшего кода, который поддерживает "+" в строках запроса и много кода, который также генерирует его. Итак, шансы хорошие, вы не сломаетесь, если используете "+" . (И, фактически, я сделал все исследования по этому поводу недавно, потому что я обнаружил главный сайт, который не смог принять "%20" в запросе GET в качестве пробела. На самом деле они не смогли декодировать никоим образом закодированный символ. использование может также иметь значение.)

Но из чистого чтения спецификаций, без языка из спецификации HTML 2.0, перенесенного в более поздние версии, URL-адреса полностью покрываются RFC3986, что означает, что пробелы должны быть преобразованы в "%20". И определенно это должно быть так, если вы запрашиваете что-либо, кроме HTML-документа.

Ответ 4

Лучше всегда кодировать пробелы как %20, а не как "+" .

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

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

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

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

Ответ 5

Какая разница: см. другие ответы.

При использовании + вместо %20? Используйте +, если по какой-то причине вы хотите сделать строку запроса URL (?.....) или хеш-фрагмент (#....) более читаемой. Пример: вы действительно можете прочитать это:

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

Но гораздо труднее прочитать: (по крайней мере для меня)

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

Я бы подумал, что + вряд ли что-то сломает, поскольку Google использует + (см. первую ссылку выше), и они, вероятно, подумали об этом. Я собираюсь использовать + сам, потому что читаемый + Google думает, что все в порядке.