URL-адреса, що кодує пробіл: + або% 20?


722

Коли кодується пробіл у URL-адресі +та коли він кодується %20?


2
Це питання було б кориснішим як кілька питань, що стосуються мови, правда?
squarecandy


3
@user запитання, на яке ви посилаєтесь, було задано пізніше, роблячи його дуппером, а не цим.
Войовничий шимпанзе

Відповіді:


425

З Вікіпедії (наголос та посилання додано):

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

Отже, реальне відсоткове кодування використовує, %20коли дані форми в URL-адресах знаходяться в модифікованій формі, яка використовує +. Тож ви, швидше за все, бачите лише +URL-адреси в рядку запиту після ?.


2
Отже + кодування технічно буде кодуванням багаточастинних / форм-даних, тоді як відсоткове кодування - це застосовано / x-www-form-urlencoded?
до н.

17
@BC: ні - multipart/form-dataвикористовує кодування MIME; application/x-www-form-urlencodedвикористовує +і правильно кодовані URI %20.
МакДауелл

8
"Отже, ви, швидше за все, бачите + у URL-адресах у рядку запиту після?" Це заниження. Ніколи не слід бачити "+" у частині URL-адреси шляху, оскільки він не буде робити те, що ви очікуєте (пробіл).
Адам Гент

34
Тому в основному: ціль подання GET - це http://www.bing.com/search?q=hello+worldі ресурс з простором у назвіhttp://camera.phor.net/cameralife/folders/2012/2012-06%20Pool%20party/
William Entriken

8
Зауважте, що для посилань електронної пошти вам потрібно% 20, а не + після ?. Наприклад, mailto:support@example.org?subject=I%20need%20help. Якщо ви спробували це з +, електронний лист відкриється з + es замість пробілів.
Сигморал

287

Ця плутанина пов’язана з тим, що 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: bobby@www.lunatech.com: 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: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до ?і +після.

Джерело


>> Ви повинні мати% 20 перед? і + після вибачення за дурне запитання. Я дещо знаю, що параметр хештегу використовується після "?" параметр питання питання. Хоча це якось інакше, оскільки використання "#" не перезавантажує сторінку. Але я намагався використовувати знак 20 і + після хештегу "#", і, здається, це не працює. Який з них потрібно використовувати після "#"?
Філсіб

@Philcyb Ви могли б прочитати це en.wikipedia.org/wiki/Percent-encoding
Матас Вайткевічус

Чи частина запиту насправді має "офіційний" стандарт? В основному я вважав, що ця частина специфічна для додатків. 99,99% додатків використовують key1=value1&key1=value2там, де ключі та значення кодуються за будь-якими правилами, encodeURIComponentале AFAIK вміст частини запиту повністю залежить від програми. З іншого боку, це лише перше, #що немає офіційного кодування.
gman

Дубльована відповідь на повторне запитання! Але хм, добре, я віддав обох.
Володимир Вуканчак

3
Таке маркування компонентів ASCII є епічним.
jsejcksn

25

Я б рекомендував %20.

Ви їх важко кодуєте?

Однак це не дуже відповідає мовам. Якщо я не помиляюся, PHP urlencode()розглядає пробіли так, як +тоді, коли Python urlencode()трактує їх як %20.

Редагувати:

Здається, я помиляюся. Python's 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+'

Не жорстке кодування. Намагаючись визначити з естетичної точки зору, як будуть виглядати мої URL-адреси, що містять пробіли.
до н.

Привіт, я також розгублений, коли користувач подає HTML-форму, як форма кодує простір? з яким персонажем? Чи залежить результат від браузера?
GMsoF

1
І URLEncoder.encode()метод на Java перетворює його +також.
рüффп

І тоді виникає питання, як лікувати кодування в тілі запиту POST: "Content-Type: application / x-www-form-urlencoded", де параметри мають форму "a = b & c = d", але вони взагалі не містять URL-адресу, а лише "документ". Вони створили справжній безлад у цьому питанні, і остаточно відповіді важко знайти.
fyngyrz

Perls uri_escape () розглядає їх як% 20
деякийкористувач

16

Простір може бути кодований лише до "+" в "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 ". Отже, лише після "?" Пробіли можна замінити плюсами . В інших випадках пробіли повинні бути закодовані до% 20. Але оскільки важко правильно визначити контекст, найкраща практика ніколи не кодує пробіли як "+".

Я б рекомендував відсотково кодувати всі символи, крім "незарезервованого", визначеного в RFC-3986, p.2.3

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

Реалізація залежить від обраної вами мови програмування.

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


1
Чому хтось повинен піклуватися про специфікацію HTML, якщо запитуваний ресурс не HTML? Я бачив "+" у деяких веб-API, які не відповідають HTML, наприклад, ви запитуєте PDF. Я вважаю неправильним, що вони не використовують "% 20".
Неймовірний січень

@TheincredibleJan, я згоден з тобою. Ось що стосується моєї відповіді.
Максим Масютін

1
@MaximMasiutin Коли у вашій відповіді сказано "Це МОЖЕ, а не ОБОВ'ЯЗКОВО", на яку специфікацію ви звертаєтесь? Я намагаюся знайти специфікацію, яка має її як можливо. У w3.org/TR/1999/REC-html401-19991224/interact/… використання "+" (у розділі запитів) знаходиться в розділі "must" специфікації.
Йосиф H

2
@JosephH - дякую за вашу замітку. Це моя особиста думка щодо МОЖА. Я відредагував пост. Я мав на увазі те, що специфікація HTML, яку ви вказали, визначає "+", але в контексті URL застосовуються інші правила, які дозволяють також кодувати пробіли як% 20.
Максим Масютін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.