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

Ответы:

481

+означает пробел только в 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

bobince
источник
5
действительно я запутался, у меня вопрос такой, когда браузер делает первую форму, а когда делает второй фомр?
Мухаммед Хьюди
11
Браузер создаст query+name=query+valueпараметр из формы с помощью <input name="query name" value="query value">. Он не будет query%20nameсоздан из формы, но использовать его вместо этого совершенно безопасно, например. если вы подаете заявку вместе для себя XMLHttpRequest. Если у вас есть URL с пробелом, например <a href="http://www.example.com/foo bar/">, браузер закодирует его, чтобы %20вы могли исправить свою ошибку, но, вероятно, лучше не полагаться на это.
bobince
6
какие функции на яваскрипт макияжа foo barв foo+bar?
Сисир
21
@Sisir: нет функции JS, которая будет выполнять кодирование формы URL. Вы можете сделать это, encodeURIComponent(s).replace(/%20/g, '+')если вам действительно нужно+
bobince
2
Это очень, очень запутанный пример чего-то, что закодировано в форме. Это не имеет ничего общего с URL.
Дейв Ван ден Эйнде
54

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

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

cerberos
источник
6
@DaveVandenEynde Почему бы и нет?
Цербер
10
потому что это неправильно. Это часть старого медиа-типа application / x-www-form-urlencoded, который не применяется к URL-адресам. Кроме того, decodeURIComponentне декодирует это.
Дейв Ван ден Эйнде
3
Да, он, вероятно, скопирован из RFC 1630 и никогда не был стандартом. tools.ietf.org/html/rfc3986 является стандартом (снова обновлен для IPv6 или чего-то еще). Конечно, браузеры все еще «поддерживают» его, но что это значит? Код сервера или клиента читает строку запроса и декодирует ее, а не браузер. Браузер просто передает его назад и вперед, и, поскольку он +является зарезервированным символом, он будет сохранен браузером.
Дейв Ван ден Эйнде
18
Google использует + для пробелов в своих поисковых URL ( google.com/#q=perl+equivalent+to+php+urlencode+spaces+as+%2B ).
Джастин
2
К вашему сведению: Rails также декодирует пробелы в +по умолчанию ( { foo: 'bar bar'}.to_query=> foo=bar+bar)
wrtsprt
46

Итак, ответы здесь немного неполные. Использование «% 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-документа.

zgwortz
источник
Чтобы добавить в свой ответ, Chrome по умолчанию кодирует пробелы в URL-адресах как %20( <a href="?q=a b">), но при отправке формы он использует +знак. Вы можете переопределить это, явно используя +sign ( <a href="?q=a+b">) или отправив форму используя XMLHTTPRequest.
x-
Действительно трудно понять цель добавления URLSearchParams developers.google.com/web/updates/2016/01/urlsearchparams , который работает некоторым устаревшим способом (сериализуйте SPACE в «+»). Это даже не поддерживается в IE11!
Нимфетамин
9

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

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

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

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

unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
Максим Масютин
источник
1
В .Net Framework UrlEncode использует '+' в QueryString, но в современном .Net Core используется% 20
Майкл Фрейдгейм
@ MiFreidgeimSO-stopbeingevil Спасибо, что сообщили нам об этом. Кажется, что современный .Net Core решил быть более последовательным и совместимым.
Максим Масютин
2

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

Когда использовать +вместо %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 использует +(см. 1-ю ссылку выше), и они, вероятно, думали об этом. Я собираюсь использовать +себя только потому, что читабельно + Google считает, что все в порядке.

KajMagnus
источник
7
Я говорю, что аргумент «читабельность» - лучшая защита для «+». Аргумент "Google делает это" ошибочен en.wikipedia.org/wiki/Argument_from_authority
FlipMcF
2
@FlipMcF Ложная страница Википедии, основанная на аргументе от авторитета, о том, «когда авторитет цитируется по теме, находящейся вне сферы их компетенции, или когда цитируемый авторитет не является истинным экспертом » - однако я думаю, что компьютеры, HTTP и URL Кодирование - это то, что находится в сфере компетенции Google.
КаджМагнус
3
@FlipMcF Цитирование поведения Google, в данном случае, является допустимым аргументом для использования «+» в URL. Дело не в том, что Google является авторитетом, а в том, что Google, вероятно, является крупнейшей интернет-компанией, и если они что-то предпримут, весьма вероятно, что браузеры однажды решат прекратить поддерживать эту практику. Кроме того, Google Chrome является одним из браузеров с наибольшей долей, и они будут поддерживать все, что Google хочет. В целом, я бы сказал, что ни у кого, использующего «+» вместо «% 20», не будет проблем из-за этого в обозримом будущем.
jdferreira
Я хотел бы продолжить этот аргумент в другом месте, где есть призыв к популярности, чтобы отказаться признать призыв к власти. По крайней мере, мы все можем согласиться в одном: «+» превосходит «% 20»
FlipMcF
1
На самом деле, URL с% 20 намного легче читать, потому что (настольные) браузеры показывают декодированный URL в нижней части окна, если навести курсор мыши на ссылку. Знаки плюса отображаются без изменений.
Мартин