Кодирование пробелов в URL: + против %20 - полное руководство
Узнайте, когда использовать + против %20 для кодирования пробелов в URL. Понимайте стандарты RFC 3986, соглашения для query string и лучшие практики для веб-разработки и интеграции API.
Кодирование пробелов в URL: Когда использовать + вместо %20
Основное различие между + и %20 в кодировании пробелов в URL заключается в их контексте и стандартах: %20 является стандартом процентного кодирования, определенным в RFC 3986 для представления пробелов в путях URL и фрагментах, в то время как + - это соглашение, используемое в основном в строках запросов и данных формы в соответствии со стандартом application/x-www-form-urlencoded. Использование неправильной кодировки может привести к проблемам с парсингом, поскольку + не универсально декодируется в пробелы во всех компонентах URL.
Содержание
- Основы кодирования пробелов в URL
- Когда использовать %20
- Когда использовать +
- Ключевые различия и лучшие практики
- Распространенные проблемы и решения
- Примеры реализации
- Заключение
Основы кодирования пробелов в 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 |
Ключевые различия
- Поведение декодирования:
decodeURIComponent()в JavaScript не преобразует + в пробел, в то время как преобразует %20 - Совместимость с сервером: Некоторые серверы могут корректно не декодировать + в сегментах пути
- Широта поддержки: %20 работает универсально во всех компонентах URL, + зависит от контекста
Как отмечено в обсуждениях Web Share Target: “decodeURIComponent() в JavaScript НЕ декодирует + (он просто оставляет его как +). Это означает, что каждый клиентский декодер должен специально заменять U+002B (+) на U+0020 (ПРОБЕЛ) перед запуском decodeURIComponent().”
Распространенные проблемы и решения
Проблемы кодирования пути
Проблема: Использование + в путях URL вызывает сбои парсинга на сервере
Решение: Всегда используйте %20 для путей и фрагментов
// Неправильно - может вызвать проблемы
const url = window.location.href.replace(/ /g, '+');
// Правильно - соответствие RFC 3986
const url = window.location.href.replace(/ /g, '%20');
Несогласованность в строке запроса
Проблема: Смешанная кодировка в параметрах запроса
Решение: Будьте последовательны - либо используйте + для всех пробелов в запросе, либо %20 для универсальной совместимости
Обработка данных формы
Проблема: Сервер ожидает %20, но получает + (или наоборот)
Решение: Сопоставьте кодировку с тем, что ожидает ваш сервер
Примеры реализации
Построение URL в 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 с обработкой обеих кодировок
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. Ключевые выводы:
- Всегда используйте %20 для путей URL и фрагментов - это соответствует стандарту RFC 3986 и обеспечивает универсальную совместимость
- Используйте + для строк запросов и данных формы - это соответствует соглашению application/x-www-form-urlencoded
- Будьте последовательны в своем приложении - смешанная кодировка может вызвать проблемы парсинга
- Учитывайте ожидания вашего сервера - некоторые серверы могут принимать только один формат или другой
- Тщательно тестируйте декодирование URL - особенно при работе с пробелами, закодированными как + и %20
Следуя этим рекомендациям, вы обеспечите корректную работу ваших URL в разных браузерах, на серверах и в API JavaScript при соблюдении правильных стандартов кодирования.
Источники
- RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
- URL encoding the space character: + or %20 - Stack Overflow
- Percent-encoding - Wikipedia
- Understanding how spaces are encoded: with encodeURI and + with URL - DEV Community
- When should space be encoded to plus (+) or %20 - Stack Overflow
- RFC 3986 Technical Reference
- Consider whether to encode SPACE as “%20” instead of “+” - W3C Web Share Target
- Translating Space Characters in URLEncoder - Baeldung