Другое

Кодирование пробелов в URL: + против %20 - полное руководство

Узнайте, когда использовать + против %20 для кодирования пробелов в URL. Понимайте стандарты RFC 3986, соглашения для query string и лучшие практики для веб-разработки и интеграции API.

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

Основное различие между + и %20 в кодировании пробелов в URL заключается в их контексте и стандартах: %20 является стандартом процентного кодирования, определенным в RFC 3986 для представления пробелов в путях URL и фрагментах, в то время как + - это соглашение, используемое в основном в строках запросов и данных формы в соответствии со стандартом application/x-www-form-urlencoded. Использование неправильной кодировки может привести к проблемам с парсингом, поскольку + не универсально декодируется в пробелы во всех компонентах URL.


Содержание


Основы кодирования пробелов в URL

Кодирование URL служит механизмом для безопасного включения специальных символов в веб-адреса. Согласно RFC 3986, официальному стандарту, регулирующему синтаксис URI, пробелы считаются небезопасными символами, которые должны быть закодированы для сохранения целостности URL и предотвращения конфликтов парсинга.

Метод кодирования значительно варьируется в зависимости от того, какая часть URL содержит пробел:

  • Сегменты пути/фрагменты: Должны использовать %20
  • Параметры запроса: Могут использовать либо %20, либо +
  • Данные формы: Традиционно используют +

“Процентно закодированный октет кодируется как триплет символов, состоящий из символа ‘%’ за которым следуют две шестнадцатеричные цифры, представляющие числовое значение этого октета. Например, ‘%20’ - это процентное кодирование для двоичного октета ‘00100000’ (ABNF: %x20), который в US-ASCII соответствует символу пробела (SP).” RFC 3986 Technical Reference


Когда использовать %20

Пути URL и фрагменты

%20 является обязательным при кодировании пробелов в путях URL, фрагментах или любой части перед строкой запроса. Это следует строгой спецификации RFC 3986.

Например:

  • https://example.com/my file.html
  • https://example.com/my%20file.html

Технические требования

Согласно Stack Overflow, “пробел в части фрагмента пути должен быть закодирован как ‘%20’ (и ни в коем случае не ‘+’), в то время как символ ‘+’ в части фрагмента пути может остаться без кодирования.”

Поведение браузеров

Современные браузеры автоматически преобразуют пробелы в вводимых URL в %20, что отражает это требование кодирования пути.


Когда использовать +

Строки запросов и параметры

+ допустим и широко используется в строках запроса URL (после символа ?). Это соглашение исходит из стандарта application/x-www-form-urlencoded, используемого в HTML-формах.

Например:

  • https://example.com/search?q=my+query
  • https://example.com/search?q=my%20query

Кодирование данных формы

При отправке форм пробелы традиционно кодируются как + в соответствии с документацией MDN: “Для application/x-www-form-urlencoded пробелы должны заменяться на +, поэтому может потребоваться выполнить замену encodeURIComponent() с последующей заменой ‘%20’ на ‘+’.”

JavaScript URLSearchParams

API JavaScript URLSearchParams использует + для пробелов, следуя стандартам кодирования форм: “Это объясняет, почему пробелы заменяются на ‘+’ в URLSearchParams, так как он следует стандарту application/x-www-form-urlencoded.”


Ключевые различия и лучшие практики

Таблица сравнения контекста

Компонент URL Предпочтительная кодировка Ссылка на стандарт Пример
Путь/Фрагмент %20 RFC 3986 /docs/my%20file.pdf
Строка запроса + (или %20) Кодирование формы ?q=hello+world
Данные формы + application/x-www-form-urlencoded name=John+Doe

Ключевые различия

  1. Поведение декодирования: decodeURIComponent() в JavaScript не преобразует + в пробел, в то время как преобразует %20
  2. Совместимость с сервером: Некоторые серверы могут корректно не декодировать + в сегментах пути
  3. Широта поддержки: %20 работает универсально во всех компонентах URL, + зависит от контекста

Как отмечено в обсуждениях Web Share Target: “decodeURIComponent() в JavaScript НЕ декодирует + (он просто оставляет его как +). Это означает, что каждый клиентский декодер должен специально заменять U+002B (+) на U+0020 (ПРОБЕЛ) перед запуском decodeURIComponent().”


Распространенные проблемы и решения

Проблемы кодирования пути

Проблема: Использование + в путях URL вызывает сбои парсинга на сервере
Решение: Всегда используйте %20 для путей и фрагментов

javascript
// Неправильно - может вызвать проблемы
const url = window.location.href.replace(/ /g, '+');

// Правильно - соответствие RFC 3986
const url = window.location.href.replace(/ /g, '%20');

Несогласованность в строке запроса

Проблема: Смешанная кодировка в параметрах запроса
Решение: Будьте последовательны - либо используйте + для всех пробелов в запросе, либо %20 для универсальной совместимости

Обработка данных формы

Проблема: Сервер ожидает %20, но получает + (или наоборот)
Решение: Сопоставьте кодировку с тем, что ожидает ваш сервер


Примеры реализации

Построение URL в JavaScript

javascript
// Сегмент пути - должен использовать %20
const path = '/my documents'.replace(/ /g, '%20');
// Результат: '/my%20documents'

// Параметр запроса - можно использовать любой
const query = new URLSearchParams();
query.set('search', 'my query');
// Результат: 'search=my+query'

// Ручное кодирование для универсальной совместимости
function encodeSpaceForURL(space) {
  // Проверяем, находится ли в контексте строки запроса
  if (url.includes('?')) {
    return space.replace(/ /g, '+');
  }
  return space.replace(/ /g, '%20');
}

Обработка на стороне сервера

python
# Пример на Python с обработкой обеих кодировок
from urllib.parse import unquote, parse_qs

def parse_url_params(url):
    # Для строк запроса обрабатываем и %20, и +
    parsed = parse_qs(url.split('?')[1])
    params = {}
    for key, values in parsed.items():
        params[key] = [v.replace('+', ' ') for v in values]
    return params

Заключение

Понимание того, когда использовать + или %20 для кодирования пробелов в URL, имеет решающее значение для веб-разработки и интеграции API. Ключевые выводы:

  1. Всегда используйте %20 для путей URL и фрагментов - это соответствует стандарту RFC 3986 и обеспечивает универсальную совместимость
  2. Используйте + для строк запросов и данных формы - это соответствует соглашению application/x-www-form-urlencoded
  3. Будьте последовательны в своем приложении - смешанная кодировка может вызвать проблемы парсинга
  4. Учитывайте ожидания вашего сервера - некоторые серверы могут принимать только один формат или другой
  5. Тщательно тестируйте декодирование URL - особенно при работе с пробелами, закодированными как + и %20

Следуя этим рекомендациям, вы обеспечите корректную работу ваших URL в разных браузерах, на серверах и в API JavaScript при соблюдении правильных стандартов кодирования.


Источники

  1. RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
  2. URL encoding the space character: + or %20 - Stack Overflow
  3. Percent-encoding - Wikipedia
  4. Understanding how spaces are encoded: with encodeURI and + with URL - DEV Community
  5. When should space be encoded to plus (+) or %20 - Stack Overflow
  6. RFC 3986 Technical Reference
  7. Consider whether to encode SPACE as “%20” instead of “+” - W3C Web Share Target
  8. Translating Space Characters in URLEncoder - Baeldung
Авторы
Проверено модерацией
Модерация