Как я могу справиться с ограничениями длины строки запроса HTTP GET и все еще хочу быть спокойным?

как указано в http://www.boutell.com/newfaq/misc/urllength.html, строка HTTP-запроса имеет ограниченную длину. Он может быть ограничен клиентом (Firefox, IE, ...), сервер (Apache, IIS,...) или сетевое оборудование (applicative firewall, ...).

сегодня я сталкиваюсь с этой проблемой с формой поиска. Мы разработали форму поиска с большим количеством полей,и эта форма отправляется на сервер в качестве запроса GET, поэтому я могу пометить полученную страницу.

у нас так многие поля нашей строки запроса имеют длину 1100 байт, и у нас есть брандмауэр, который отбрасывает HTTP GET-запросы с более чем 1024 байтами. Наш системный администратор рекомендует нам использовать POST вместо этого, чтобы не было никаких ограничений.

конечно, сообщение будет работать, но я действительно чувствую поиск как GET, а не сообщение. Поэтому я думаю, что я рассмотрю наши имена полей, чтобы убедиться, что строка запроса не слишком длинная, и если я не могу, я буду прагматичным и использовать POST.

но есть ли недостаток в проектирование RESTful-сервисов? Если у нас есть ограниченная длина в запросе GET, как я могу отправить большие объекты в RESTful webservice? Например, если у меня есть программа, которая делает вычисления на основе файла, и я хочу предоставить RESTful webservice следующим образом:http://compute.com?content=<base64 file>. Это не сработает, потому что строка запроса не имеет неограниченной длины.

7 ответов


основываясь на вашем описании, IMHO вы должны использовать сообщение. Пост для размещения данных на сервере и, в некоторых случаях, получить ответ. В вашем случае вы выполняете поиск (отправляете запрос на сервер) и получаете результат этого поиска (извлекаете результат запроса).

в определении GET говорится, что он должен использоваться для извлечения уже существующего ресурса. По определению, POST-это создание нового ресурса. Это именно то, что вы делаете: создание ресурса на сервере и вернуть его! Даже если вы не сохраняете результат поиска, вы создали объект на сервере и извлекли его. Как сказал PeterMmm previsouly, вы можете сделать это с помощью POST (создать и сохранить результат запроса), а затем использовать GET для повторного выполнения запроса, но более практично сделать только POST и получить результат.

надеюсь, что это помогает! :)


спецификация HTTP фактически советует использовать POST при отправке данных на ресурс для расчета.

ваш поиск выглядит как вычисление, а не сам ресурс. Если вы все еще хотите, чтобы результаты поиска были ресурсом, создайте маркер для идентификации конкретного результата поиска и перенаправьте агент пользователя на этот ресурс.

затем вы можете удалить маркеры результатов поиска после некоторого количества время.

пример

POST /search
query=something&category=c1&category=c2&...

201 Created
Location: /search/01543164876

затем

GET /search/01543164876

200 Ok
... your results here...

таким образом, браузеры и прокси все еще могут кэшировать Результаты поиска, но вы отправляете свои параметры запроса с помощью POST.

редактировать

разъяснить, 01543164876 здесь представлен уникальный идентификатор ресурса, представляющего ваш поиск. Эти 2 запроса в основном означают: создать новый объект поиска с этими критериями, а затем получить результаты связанный с созданным объектом поиска.

этот идентификатор может быть уникальным идентификатором, генерируемым для каждого нового запроса. Это означает, что ваш сервер будет пропускать объекты" поиска", и вам придется регулярно очищать их с помощью стратегии кэширования.

или это может быть хэш всех критериев поиска, фактически представляющих поиск, запрошенный пользователем. Это позволяет повторно использовать идентификаторы, так как воссоздание поиска возвращает существующий идентификатор, который может быть (или не может) уже кэширован.


отдых-это способ делать вещи, а не протокол. Даже если вы не любите публиковать, когда это действительно GET, это сработает.

Если вы будете / должны остаться с" стандартным " определением GET, POST и т. д. чем, возможно, рассмотреть вопрос о публикации запроса, этот запрос будет храниться на сервере с идентификатором запроса и запросить запрос позже с GET by id.


путаница вокруг GET является ограничением браузера. Если вы создаете интерфейс RESTful для приложения A2A или P2P, то нет никаких ограничений на длину вашего GET.

теперь, если вы хотите использовать браузер для просмотра интерфейса RESTful (он же во время разработки/отладки), вы столкнетесь с этим ограничением, но есть инструменты, чтобы обойти это.


по поводу вашего примера:http://compute.com?content={base64file}, Я бы использовал POST, потому что вы загружаете "что-то" для вычисления. Для меня это "что-то" больше похоже на ресурс как простой параметр.

в отличие от этого в обычном поиске я бы начал придерживаться GET и параметров. Вы делаете это намного проще для api-клиентов, чтобы протестировать и поиграть с вашим api. Сделайте доступ только для чтения (который в большинстве случаев является большинством трафика) максимально простым!

но дилемма больших строк запроса является допустимым ограничением GET. Здесь я бы пошел прагматично, пока вы не достигнете этого предела, идите с GET и url-params. Это будет работать в 98% случаев поиска. Только действуйте, Если вы нажмете этот предел, а затем также введете сообщение с полезной нагрузкой (с mime-type Content-Type: application/x-www-form-urlencoded).

у вас есть больше реальных примеров?


5 лет спустя, кажется, существует еще один жизнеспособный вариант-использовать GETтело сообщения. Я включаю этот ответ в качестве альтернативы всем предложениям выше, хотя у него есть свои ограничения (сделайте некоторые исследования).


Это легко. Используйте POST. HTTP не накладывает ограничения на длину URL-адреса для GET, но серверы делают это. Будьте прагматичны и обходите это с помощью POST.

вы также можете использовать тело GET (это разрешено), но это двойной удар в том, что это неправильное использование и, вероятно, будет иметь проблемы с сервером.