rest - телом - тело запроса post




HTTP GET с телом запроса (12)

Какой сервер будет игнорировать его? - fijiaaron Aug 30 '12 в 21:27

Google, например, делает хуже, чем игнорирует его, он будет считать это ошибкой !

Попробуйте сами с помощью простого netcat:

$ netcat www.google.com 80
GET / HTTP/1.1
Host: www.google.com
Content-length: 6

1234

(за содержимым 1234 следует CR-LF, так что это всего 6 байтов)

и вы получите:

HTTP/1.1 400 Bad Request
Server: GFE/2.0
(....)
Error 400 (Bad Request)
400. That’s an error.
Your client has issued a malformed or illegal request. That’s all we know.

Вы также получаете 400 Bad Request от Bing, Apple и т. Д., Которые обслуживаются AkamaiGhost.

Поэтому я бы не советовал использовать запросы GET с сущностью тела.

Я разрабатываю новый веб-сервис RESTful для нашего приложения.

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

В качестве альтернативы я хочу, чтобы люди могли указать эти параметры в теле запроса. HTTP/1.1 явно не запрещает это. Это позволит им указать больше информации, может упростить определение сложных XML-запросов.

Мои вопросы:

  • Это хорошая идея?
  • Будут ли у клиентов HTTP проблемы с использованием органов запроса в запросе GET?

HTTP/1.1


Elasticsearch принимает запросы GET с телом. Даже кажется, что это предпочтительный способ: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/common-options.html#_request_body_in_query_string

Некоторые клиентские библиотеки (например, драйвер Ruby) могут записывать команду cry в stdout в режиме разработки и широко используют этот синтаксис.


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

Также не принимаются большие решения, но отправка тела GET может предотвратить проблемы для некоторых клиентов - и некоторых серверов.

Выполнение POST может иметь препятствия с некоторыми рамками RESTish.

Джулиан Решке предложил выше, используя нестандартный HTTP-заголовок, такой как «ПОИСК», который может быть изящным решением, за исключением того, что он даже менее вероятен для поддержки.

Возможно, наиболее продуктивным будет список клиентов, которые могут и не могут выполнить каждый из указанных выше.

Клиенты, которые не могут отправить GET с телом (что я знаю):

  • XmlHTTPRequest Fiddler

Клиенты, которые могут отправить GET с телом:

  • большинство браузеров

Серверы и библиотеки, которые могут извлекать тело из GET:

  • апаш
  • PHP

Серверы (и прокси), которые разделяют тело от GET:

  • ?

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


Из RFC 2616, раздел 4.3 , «Тело сообщения»:

Сервер ДОЛЖЕН читать и пересылать тело сообщения по любому запросу; если метод запроса не содержит определенную семантику для тела-объекта, тогда тело сообщения ДОЛЖНО игнорироваться при обработке запроса.

То есть серверы должны всегда считывать любой предоставленный тело запроса из сети (проверьте Content-Length или прочитайте фрагментированное тело и т. Д.). Кроме того, доверенные лица должны направлять любой такой орган запроса, который они получают. Затем, если RFC определяет семантику тела для данного метода, сервер может фактически использовать тело запроса при генерации ответа. Однако, если RFC не определяет семантику для тела, сервер должен игнорировать его.

Это соответствует цитате из Филдинга выше.

В разделе 9.3 «GET» описывается семантика метода GET и не упоминается тела запроса. Поэтому сервер должен игнорировать любой орган запроса, который он получает по запросу GET.


Как насчет несогласованных заголовков с кодировкой base64? "SOMETHINGAPP-Титулы: sdfSD45fdg45 / СОС"

Ограничения длины hm. Не можете ли вы сделать обработку POST различать значения? Если вам нужны простые параметры, такие как сортировка, я не понимаю, почему это было бы проблемой. Наверное, ты уверен, что беспокоишься.


Ни restclient, ни консоль REST не поддерживают это, но curl делает.

Спецификация HTTP указана в разделе 4.3

Тело сообщения НЕ ДОЛЖНО быть включено в запрос, если спецификация метода запроса (раздел 5.1.1) не позволяет отправлять тело объекта в запросы.

Раздел 5.1.1 перенаправляет нас на раздел 9.x для различных методов. Ни один из них явно не запрещает включение тела сообщения. Тем не мение...

В разделе 5.2 говорится

Точный ресурс, идентифицированный с помощью интернет-запроса, определяется путем изучения поля Request-URI и заголовка Host.

и в разделе 9.3 говорится

Метод GET означает получение любой информации (в форме объекта), идентифицируемой Request-URI.

В совокупности они предполагают, что при обработке запроса GET серверу не требуется проверять что-либо другое, что поле заголовка Request-URI и Host.

Таким образом, спецификация HTTP не мешает вам отправлять тело сообщения с GET, но есть достаточная двусмысленность, что меня не удивит, если он не будет поддерживаться всеми серверами.


Согласно XMLHttpRequest, это неверно. Из standard :

4.5.6 Метод send()

client . send([body = null])

Инициирует запрос. Необязательный аргумент предоставляет тело запроса. Аргумент игнорируется, если метод запроса - GET или HEAD .

Выдает исключение InvalidStateError если состояние не открыто или установлен флаг send() .

Метод send( body ) должен выполнять следующие действия:

  1. Если состояние не открыто , InvalidStateError исключение InvalidStateError .
  2. Если установлен флаг send() , InvalidStateError исключение InvalidStateError .
  3. Если метод запроса GET или HEAD , установите для тела значение null.
  4. Если тело равно null, перейдите к следующему шагу.

Хотя, я не думаю, что это должно быть, потому что запрос GET может потребовать большого содержимого тела.

Итак, если вы полагаетесь на XMLHttpRequest браузера, скорее всего, это не сработает.


Хотя вы можете это сделать, поскольку это явно не запрещено спецификацией HTTP, я бы предложил избежать этого просто потому, что люди не ожидают, что что-то будет работать таким образом. В цепочке запросов HTTP есть много фаз, и, хотя они «в основном» соответствуют спецификации HTTP, единственное, что вы уверены, это то, что они будут вести себя традиционно, используя веб-браузеры. (Я думаю о вещах, таких как прозрачные прокси, ускорители, инструментальные средства A / V и т. Д.)

Это дух, лежащий в основе принципа надежности, грубо говоря, «будьте либеральными в том, что вы принимаете, и консервативен в том, что вы отправляете», вы не хотите без каких-либо оснований указывать границы спецификации.

Однако, если у вас есть веская причина, пойдите для этого.


Я бы не посоветовал это, это противоречит стандартным практикам и не предлагает этого взамен. Вы хотите сохранить контент для тела, а не параметры.


Я расстроен тем, что REST, поскольку протокол не поддерживает OOP, и метод Get является доказательством. В качестве решения вы можете сериализовать DTO в JSON, а затем создать строку запроса. На стороне сервера вы можете десериализовать строку запроса в DTO.

Посмотрите:

Подход на основе сообщений может помочь вам решить ограничение метода Get. Вы можете отправить любой DTO, как с телом запроса

Структура веб-сервиса Nelibur обеспечивает функциональность, которую вы можете использовать

var client = new JsonServiceClient(Settings.Default.ServiceAddress);
var request = new GetClientRequest
    {
        Id = new Guid("2217239b0e-b35b-4d32-95c7-5db43e2bd573")
    };
var response = client.Get<GetClientRequest, ClientResponse>(request);

as you can see, the GetClientRequest was encoded to the following query string

http://localhost/clients/GetWithResponse?type=GetClientRequest&data=%7B%22Id%22:%2217239b0e-b35b-4d32-95c7-5db43e2bd573%22%7D

Комментарий Роя Филдинга о включении тела с запросом GET .

Да. Другими словами, любому сообщению HTTP-запроса разрешено содержать тело сообщения и, следовательно, должно анализировать сообщения с учетом этого. Однако семантика сервера для GET ограничена таким, что тело, если оно есть, не имеет семантического значения для запроса. Требования к разбору отдельно от требований к семантике метода.

Итак, да, вы можете отправить тело с помощью GET, и нет, никогда не бывает так полезно.

Это часть многоуровневой конструкции HTTP / 1.1, которая снова станет понятной после того, как спецификация будет разделена (работа продолжается).

....Рой

Да, вы можете отправить тело запроса с GET, но оно не должно иметь никакого значения. Если вы дадите это значение, проанализировав его на сервере и изменив свой ответ на основе его содержимого , вы игнорируете эту рекомендацию в спецификации HTTP / 1.1, раздел 4.3 :

[...], если метод запроса не содержит определенную семантику для тела сущности, тогда тело сообщения SHOULD игнорироваться при обработке запроса.

И описание метода GET в спецификации HTTP / 1.1, раздел 9.3 :

Метод GET означает получение любой информации ([...]), идентифицируемой Request-URI.

в котором указано, что тело запроса не является частью идентификации ресурса в запросе GET, а только URI запроса.





http-get