Вопросы и ответы5 мин чтения

Кодирование пробелов в URL: %20 или + (когда что использовать)

%20 — это стандартное percent-encoding кодирование символа пробела согласно RFC 3986, которое следует использовать в путях URL и в большинстве контекстов. Знак + обозначает пробел только в формате application/x-www-form-urlencoded, применяемом при отправке HTML-форм и в некоторых строках запроса.

Что означает %20?

%20 — это percent-encoding представление символа пробела (код ASCII 32, шестнадцатеричное 0x20), определённое в RFC 3986. Это стандартный способ обозначать пробелы в любой части URI, включая сегменты пути, строки запроса и идентификаторы фрагментов.

Когда вы видите %20 в URL, это просто означает «здесь пробел». Например, https://example.com/my%20file.pdf ссылается на ресурс с именем «my file.pdf». Последовательность %20 одинаково понимается всеми веб-серверами, браузерами и HTTP-библиотеками.

Что означает + в URL?

Использование знака + для обозначения пробела пришло из типа содержимого application/x-www-form-urlencoded, который был определён в спецификации HTML для кодирования данных форм. Когда HTML-форма отправляется методом GET, браузер кодирует пробелы как + в получившейся строке запроса.

Например, если вы введёте «hello world» в форму поиска и отправите её, браузер сформирует URL вида https://example.com/search?q=hello+world. Здесь + означает «пробел», но только потому, что строка запроса использует формат form-urlencoded.

Важно отметить, что за пределами формата application/x-www-form-urlencoded знак + не имеет никакого специального значения. В пути URL вроде /files/my+file.pdf символ + — это буквальный знак «плюс», а не пробел. Ресурс, на который идёт ссылка, буквально называется «my+file.pdf».

Ключевое различие

Фундаментальное различие заключается в том, к какой спецификации относится каждый вариант. %20 определён в RFC 3986 (URI) и работает везде в URL. Соглашение о + как пробеле определено в спецификации HTML/WHATWG для данных форм и работает только в строках запроса, которые явно рассматриваются как данные в формате form-urlencoded.

  • %20 работает в путях, строках запроса, фрагментах и во всех контекстах URI
  • + означает «пробел» только в строках запроса application/x-www-form-urlencoded
  • В путях URL + — это буквальный знак «плюс», а не пробел
  • %20 всегда безопасен; + зависит от контекста
  • Если закодировать буквальный + в данных формы, он станет %2B

Что выбрать?

Используйте %20, когда формируете URL программно, создаёте запросы к REST API, кодируете сегменты пути или когда сомневаетесь. Это универсально корректное кодирование пробелов в URI.

Используйте + только тогда, когда вы намеренно формируете данные в формате application/x-www-form-urlencoded — например, строите строки запроса, имитирующие отправку HTML-форм, или когда API явно требует этот формат.

Большинство современных API и фреймворков принимают в строках запроса и %20, и +. Тем не менее использование %20 более переносимо и позволяет избежать неоднозначности, особенно когда строка запроса может использоваться вне контекста отправки форм.

Как разные языки обрабатывают пробелы

Разные языки программирования и их стандартные библиотеки могут по умолчанию использовать для кодирования пробелов либо %20, либо +. Знание поведения по умолчанию в вашем языке поможет избежать неожиданностей.

// JavaScript
encodeURIComponent('hello world');  // "hello%20world" (%20)
new URLSearchParams({q: 'hello world'}).toString();  // "q=hello+world" (+)

// Чтобы принудительно получить %20 в строках запроса:
new URLSearchParams({q: 'hello world'}).toString().replace(/\+/g, '%20');
# Python
from urllib.parse import quote, quote_plus, urlencode

quote('hello world', safe='')    # "hello%20world" (%20)
quote_plus('hello world')        # "hello+world" (+)
urlencode({'q': 'hello world'})  # "q=hello+world" (+ по умолчанию)

# Чтобы принудительно получить %20:
urlencode({'q': 'hello world'}, quote_via=quote)  # "q=hello%20world"
// PHP
rawurlencode('hello world');  // "hello%20world" (%20)
urlencode('hello world');     // "hello+world" (+)

// rawurlencode следует RFC 3986
// urlencode следует application/x-www-form-urlencoded

Похожие статьи

Попробуйте наши бесплатные инструменты