Иногда пробелы получают URL, закодированный в +
знак, а иногда в %20
. В чем разница и почему это должно происходить?
Иногда пробелы получают URL, закодированный в +
знак, а иногда в %20
. В чем разница и почему это должно происходить?
Ответы:
+
означает пробел только в 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
query+name=query+value
параметр из формы с помощью <input name="query name" value="query value">
. Он не будет query%20name
создан из формы, но использовать его вместо этого совершенно безопасно, например. если вы подаете заявку вместе для себя XMLHttpRequest
. Если у вас есть URL с пробелом, например <a href="http://www.example.com/foo bar/">
, браузер закодирует его, чтобы %20
вы могли исправить свою ошибку, но, вероятно, лучше не полагаться на это.
foo bar
в foo+bar
?
encodeURIComponent(s).replace(/%20/g, '+')
если вам действительно нужно+
http://www.example.com/some/path/to/resource?param1=value1
Часть до знака вопроса необходима использовать% кодирующий (так %20
для пространства), после знака вопроса вы можете использовать либо %20
или +
для пространства. Если вам нужен фактический +
после использования знака вопроса %2B
.
decodeURIComponent
не декодирует это.
+
является зарезервированным символом, он будет сохранен браузером.
+
по умолчанию ( { foo: 'bar bar'}.to_query
=> foo=bar+bar
)
Итак, ответы здесь немного неполные. Использование «% 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-документа.
%20
( <a href="?q=a b">
), но при отправке формы он использует +
знак. Вы можете переопределить это, явно используя +
sign ( <a href="?q=a+b">
) или отправив форму используя XMLHTTPRequest
.
Лучше всегда кодировать пробелы как% 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 / "-" / "." / "_" / "~"
Какая разница: смотрите другие ответы.
Когда использовать +
вместо %20
? Используйте, +
если по какой-то причине вы хотите сделать строку запроса URL-адреса ( ?.....
) или хэш-фрагмент ( #....
) более читабельной. Пример: вы можете прочитать это:
https://www.google.se/#q=google+doesn%27t+encode+:+and+uses+%2B+instead+of+spaces
( %2B
= +)
Но следующее гораздо труднее читать: (по крайней мере, для меня)
Я думаю, что +
вряд ли что-то сломает, поскольку Google использует +
(см. 1-ю ссылку выше), и они, вероятно, думали об этом. Я собираюсь использовать +
себя только потому, что читабельно + Google считает, что все в порядке.