Как обойти ограничение длины URL в HTTP запросах
Что проверяют
Понимаете ли вы, что лимит длины URL задаёт не протокол, а конкретные браузеры, серверы и прокси на пути запроса, и умеете ли вы это протестировать. Следом спрашивают, какой код ответа ожидать при превышении и что предложить разработчикам.
Как отвечать
Начните с фактов. Стандарт HTTP (RFC 9110) жёсткого лимита не задаёт, он лишь рекомендует поддерживать URI длиной хотя бы 8000 октетов. Реальные ограничения ставят серверы: у nginx строка запроса упирается в large_client_header_buffers (по умолчанию 8 КБ), у Apache в LimitRequestLine (около 8 КБ), у Tomcat в maxHttpHeaderSize. Современные браузеры держат гораздо более длинные адреса, а цифра «2000 символов» тянется со времён старого Internet Explorer. Отдельно режут балансировщики, CDN и WAF.
При превышении сервер обычно отвечает 414 URI Too Long, иногда 400, а при переполнении заголовков 431 Request Header Fields Too Large.
Что предложить разработчикам:
- данные в тело:
POSTс JSON, обычный выход для сложных фильтров и поиска. Минус: такой запрос не кэшируется какGET; - метод
QUERY: безопасный запрос с телом, который продвигает IETF, но поддержка в серверах, прокси и клиентах пока неполная; - сохранённый поиск: клиент создаёт фильтр
POST-запросом, а дальше передаёт в URL только его идентификатор; - короткие параметры: ID вместо полных значений, без дублирования массивов.
Base64 задачу не решает: он увеличивает объём примерно на треть.
Как тестировщик вы проверяете границу: запрос чуть ниже лимита, ровно на лимите и выше, причём по всей цепочке, напрямую в сервис и через шлюз. Ожидаемый код и понятное сообщение фиксируете в требованиях.
Где спотыкаются
Называют «2048 символов» лимитом HTTP. Такого лимита в протоколе нет, это ограничение одного старого браузера.
Предлагают GET с телом. Семантика тела у GET не определена, прокси и часть клиентов его отбрасывают.
Забывают про безопасность: длинный URL с персональными данными оседает в логах серверов, истории браузера и заголовке Referer. Это отдельный дефект, даже если лимит не превышен.