Инструменты разработчика · Кодер и декодер URL
Пробелы в ссылках для скачивания файлов: почему %20, + и необработанный пробел — это не одно и то же
· Почему это важно
URL-кодировка http рабочий процесс разработчика
Файл под названием «Отчет за 3 квартал (окончательный).pdf» можно связать тремя разными способами, и только один из них является достоверно правильным. В этом посте объясняется, почему имена файлов нарушают ссылки на скачивание и как их закодировать, чтобы каждый клиент согласился.
Загрузка, которая не удалась для некоторых пользователей и работает для других — имя файла с пробелами и знаком плюса.
Файлы типа «Q3 report.pdf» работают нормально, если хранятся локально, но у некоторых пользователей не удается загрузить их по ссылкам, в то время как у других все получается без проблем. Необработанные пробелы недопустимы в URL-адресах согласно спецификации RFC 3986. Браузеры допускают их использование в адресной строке, но клиенты HTTP категорически отвергают их. Понимание %20, знаков плюс и необработанных пробелов абсолютно необходимо для надежного распространения. Различие между методами кодирования напрямую влияет на показатели успешной загрузки на разных платформах, различных инструментах автоматизации и реализациях клиентов HTTP по всему миру. Разработчики должны понимать это различие при создании систем загрузки. Контекст имеет значение для выбора кодировки и совместимости системы.
Разработчики должны выбирать между необработанными пробелами, %20 или знаками плюса при создании ссылок для загрузки. Тестирование с помощью Curl, wget и Python показывает, какие клиенты обеспечивают соблюдение требований RFC. Загрузка в браузере завершается успешно благодаря устранению ошибок, но интеграция API завершается сбоем при обнаружении незакодированных пробелов.
Почему необработанное пространство недопустимо в URL — и почему браузеры допускают его в адресной строке, а клиенты HTTP — нет
Необработанные пробелы в URL-адресах имеют исторические корни в разработке протоколов. URL-адреса проходят через системы, рассматривая пробелы как разделители между токенами. Пробел в URL может быть ошибочно интерпретирован как его терминатор. HTTP клиенты, читающие из командной строки, обрезают первые пробелы. Эта основополагающая конструкция остается в реализациях протокола и вряд ли изменится.
Браузеры допускают необработанные пробелы путем автоматического преобразования в %20 перед отправкой запросов HTTP. Такое удобное для пользователя поведение скрывает требования протокола от конечных пользователей, вставляющих URL-адреса в адресную строку. В автоматизированных системах этот уровень восстановления отсутствует. Скрипты не работают с URL-адресами с необработанными пробелами. Почтовые клиенты сталкиваются с ошибками при открытии таких ссылок.
%20 вместо + в сегменте пути — соглашение о кодировании формы, которое не применяется к путям.
%20 и знаки плюс представляют собой фундаментальное различие в контекстах кодирования URL. В сегментах пути пробелы должны кодироваться как %20 согласно RFC 3986. Знак плюс не является кодировкой пробела в путях. Это соглашение возникло в кодировке формы HTML, где оно служит кодировкой пробелов в строках запроса. Разработчики часто неправильно применяют правила формы к путям.
Соглашения о кодировании форм, допускающие использование знаков плюс, не применяются к путям с различными структурными требованиями. В строках запроса параметры-разделители амперсанды и равенства. Использование плюса для пробелов в значениях запроса не создает двусмысленности, поскольку плюс не является разделителем. В путях плюс не имеет особого значения. Смешение соглашений приводит к неработающим ссылкам для скачивания.
Имена файлов, отличные от ASCII — UTF-8 процентное кодирование и ключи хранения объектов, в которых хранится необработанное имя.
Имена файлов, отличные от ASCII, требуют процентного кодирования UTF-8 перед безопасной передачей в URL-адресах. Имя файла типа «Über report.pdf» содержит «Ü» (U+00DC) за пределами диапазона ASCII. Кодировка UTF-8 преобразует это в байты C3 9C. Эти байты кодируются в процентах как %C3%9C в URL-адресах. Каждый байт UTF-8 получает свой собственный триплет, создавая более длинные закодированные имена файлов.
Сервисы объектного хранения, такие как Amazon S3, представляют интересные случаи для имен файлов, отличных от ASCII. Некоторые системы допускают необработанные UTF-8 байты в ключах, тогда как другие требуют процентного кодирования. Стратегия кодирования зависит от поставщиков хранилища и использования URL. Для доступа на основе URL требуется процентное кодирование UTF-8. Разработчики должны координировать уровни хранения и генерации URL.
Рабочий пример: кодирование «Отчета Über Q3 (окончательный)+notes.pdf» для пути — точный результат и почему + должен стать %2B
Рабочий пример: кодировка «Über report (final)+notes.pdf» демонстрирует полную кодировку. Имя файла содержит пробелы, символы, отличные от ASCII, и буквальный плюс. Кодировка UTF-8 "Ü" дает %C3%9C. При кодировании пути пробелы становятся %20 (в отличие от кодирования формы с использованием плюса). Буквальный плюс становится %2B. Круглые скобки кодируются как %28 и %29. Результат: %C3%9CberQ3%20отчет%20%28final%29%2Bnotes.pdf.
Тестирование с помощью кодера и декодера URL показывает точное преобразование. Вставка имени файла в однозначный режим создает правильные сегменты с процентным кодированием с использованием правил пути. Инструмент сохраняет разделители пути при кодировании только компонентов имени файла. Визуальное сравнение входных и выходных данных делает правила понятными и проверяемыми перед началом производства. Сравните это с режимом формы, чтобы увидеть контекстные различия.
Content-Disposition и параметр filename* — отдельная кодировка для приглашения на загрузку, упомянута для полноты картины.
Параметры Content-Disposition и filename* представляют собой альтернативные уровни кодирования для запросов на загрузку. Серверы включают заголовки Content-Disposition, определяющие имена файлов для диалоговых окон загрузки. Параметр filename использует кодировку RFC 2183, а filename* использует RFC 5987 с процентной кодировкой. Браузеры интерпретируют эти заголовки, чтобы определить имена файлов сохранения. Одно и то же имя файла кодируется дважды с использованием разных схем.
Два уровня кодирования создают возможности для ошибок перекодирования. Имена файлов в кодировке URL и заголовке могут быть некорректными, если серверы и клиенты не согласны. Для максимальной совместимости разработчикам следует кодировать имена файлов в путях URL, используя процентное кодирование %20 и UTF-8, а также устанавливать заголовки Content-Disposition с декодированными именами файлов. Это гарантирует правильную работу всех клиентов и браузеров HTTP.
Чего это не касается — зарезервированные имена файлов в определенных операционных системах и особенности поставщиков услуг хранения данных.
Зарезервированные имена файлов в определенных операционных системах усложняют кодировку URL. Windows резервирует для устройств такие имена, как CON, PRN и AUX. Файлы с буквальным названием «CON.pdf» не могут существовать на NTFS. В macOS действуют соглашения об именах и расширенные правила атрибутов. Linux чувствителен к регистру. Допустимые имена файлов в кодировке URL могут быть недопустимы для хранения в некоторых системах.
Особенности поставщиков хранилищ усложняют кросс-платформенное распространение. Amazon S3 принимает ключи UTF-8 и учитывает регистр. Google Cloud Storage ведет себя аналогично с дополнительными ограничениями. В хранилище BLOB-объектов Azure действуют другие правила символов. Имена файлов, работающие на S3, могут не работать в Azure. Архитекторы должны проверить документацию поставщика и провести тестирование с реальными именами файлов, отличными от ASCII.
Вывод: кодируйте сегмент, а не URL — как однозначный режим кодера и декодера URL создает безопасное для пути имя файла.
Вывод: кодируйте сегмент, а не URL — однозначный режим кодирования и декодера URL создает имена файлов с безопасным путем. Инструмент принимает необработанные имена файлов и создает сегменты с процентным кодированием. Это предотвращает двойное кодирование и смешивание контекстов. Использование режима одного значения позволяет избежать балансировки правил кодирования путей, запросов и фрагментов. Сгенерированные сегменты можно безопасно вставлять в URL-адреса.
В лучших практиках имена файлов кодируются там, где они входят в конструкцию URL. Не думайте, что браузеры устраняют проблемы с кодировкой. Протестируйте с использованием реальных клиентов HTTP, используемых целевыми пользователями: Curl, wget, Python, Java httplib и API-интерфейсы выборки браузера. Убедитесь, что имена файлов передаются по всей системе. Кодер и декодер URL — это отправная точка, обеспечивающая правильность.