HTTP POST с параметрами запроса URL-хорошая идея или нет?

Я разрабатываю API для перехода через HTTP, и мне интересно, если с помощью команды HTTP POST, но только с параметрами запроса URL и без тела запроса, это хороший способ пойти.

вопросы:

  • "хороший веб-дизайн" требует, чтобы не идемпотентные действия отправлялись по почте. Это не идемпотентное действие.
  • легче разрабатывать и отлаживать это приложение, когда параметры запроса присутствуют в URL-адресе.
  • API не предназначен для широкое применение.
  • похоже, что запрос POST без тела займет немного больше работы, например, a Content-Length: 0 заголовок должен быть явно добавлен.
  • мне также кажется, что сообщение без тела немного противоречит ожиданиям большинства разработчиков и HTTP-фреймворков.

есть ли больше подводных камней или преимуществ для отправки параметров по запросу POST через запрос URL, а не тело запроса?

Edit: причина, по которой это находится под считается, что операции не являются идемпотентными и имеют побочные эффекты, отличные от извлечения. См.спецификация HTTP:

в частности, конвенция была установлено, что The GET и HEAD методы не должны иметь значение принятия мер другое чем возвращение. Эти методы должны считается "безопасным". Это позволяет пользователю агенты для представления других методов, такие как POST, PUT и DELETE, в особенный путь, так что пользователь осознавая тот факт, что запрашиваются небезопасные действия.

...

методы также могут иметь свойство "идемпотенция "в этом (помимо ошибки или проблемы с истечением срока действия) побочные эффекты от n > 0 идентичных запросы такие же, как для одного запрос. Методы GET, HEAD, PUT и удалить поделиться этим свойством. Также, параметры методов и трассировка должны Не имеют побочных эффектов, и так по сути идемпотентный.

7 ответов


если ваше действие не идемпотентно, то вы должны использовать POST. Если нет,то ты просто напрашиваешься на неприятности. GET, PUT и DELETE методы требуются чтобы быть идемпотентом. Представьте себе, что произойдет в вашем приложении, если клиент будет предварительно получать все возможные GET request for your service -- если это вызовет побочные эффекты, видимые клиенту, то что-то не так.

Я согласен, что отправка POST со строкой запроса, но без тела кажется странным, но я думаю, что это может быть уместно в некоторых ситуациях.

подумайте о части запроса URL-адреса как о команде ресурсу, чтобы ограничить область текущего запроса. Как правило, строки запроса используются для сортировки или фильтрации GET запрос (например,?page=1&sort=title), но я предполагаю, что это имеет смысл на POST также ограничить область (возможно, как ?action=delete&id=5).


все правы: придерживайтесь POST для не идемпотентных запросов.

Как насчет использования строки запроса URI и содержимого запроса? Ну, это действительно HTTP (см. Примечание 1), так почему бы и нет!

Это также совершенно логично: URL-адреса, включая их часть строки запроса, предназначены для расположение ресурсы. В то время как глаголы метода HTTP (POST - и его необязательное содержимое запроса) предназначены для указания действий или что делать ресурсы. Они должны быть ортогональные проблемы. (Но они не являются красиво ортогональными проблемами для частного случая ContentType=application / x-www-form-urlencoded, см. Примечание 2 ниже.)

Примечание 1: спецификация HTTP (1.1) не указывает, что параметры запроса и содержимое являются взаимоисключающими для HTTP-сервера, который принимает запросы POST или PUT. Таким образом, любой сервер может принять оба варианта. Т. е. если вы пишете сервер, ничто не мешает вам принять оба (за исключением, возможно, негибкой структуры). Как правило, сервер может интерпретировать строки запроса в соответствии с любыми правилами. Он даже может интерпретировать их с условной логикой, которая ссылается на другие заголовки, такие как Content-Type, что приводит к примечанию 2:

примечание 2: Если браузер является основным способом доступа людей к вашему веб-приложению, и application / x-www-form-urlencoded это тип контента, который они публикуют, а затем вы должны следуйте правилам для этого типа контента. И правила для application / x-www-form-urlencoded гораздо более специфичны (и, честно говоря, необычны): в этом случае вы должны интерпретировать URI как набор параметров, а не местоположение ресурса. [Это тот же момент полезности Powerlord; что может быть трудно использовать веб-формы для публикации контента на вашем сервере. Просто объяснил немного по-другому.]

Примечание 3: для чего изначально предназначены строки запроса? RFC 3986 определяет строки HTTP-запроса как часть URI, которая работает как неиерархический способ поиска ресурса.

в случае, если читатели, задающие этот вопрос, хотят спросить, Что такое хорошая архитектура RESTful: шаблон архитектуры RESTful не требует, чтобы схемы URI работали определенным образом. Архитектура RESTful занимается другими свойствами системы, такими как кэшируемость ресурсов, дизайн самих ресурсов (их поведение, возможности и представления) и удовлетворяется ли идемпотенция. Или другими словами, достижение дизайн, который очень совместим с протоколом HTTP и его набором команд метода HTTP. :-) (Иными словами, RESTful-архитектуры не очень presciptive как ресурсы расположенном.)

последнее примечание: иногда параметры запроса используются для других вещей, которые не являются ни поиском ресурсов, ни кодированием контента. Вы когда-нибудь видели параметр запроса, такой как "PUT=true" или "POST=true"? Это обходные пути для браузеров, которые не позволяют использовать методы PUT и POST. Хотя такие параметры рассматриваются как часть строки запроса URL (на проводе), я утверждаю, что они не являются частью запроса URL в духе.


вам нужны причины? Вот один:

веб-форма не может использоваться для отправки запроса на страницу, использующую сочетание GET и POST. Если для метода формы задано значение GET, все параметры находятся в строке запроса. Если для метода формы задано значение POST, все параметры находятся в теле запроса.

источник: стандарт HTML 4.01, раздел 17.13 Форма Представления


с программной точки зрения, для клиента он упаковывает параметры и добавляет их в url-адрес и проводит сообщение против GET. На стороне сервера он оценивает входящие параметры из строки запроса вместо разнесенных байтов. В основном, это стирка.

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

тем не менее, с точки зрения программиста, я предпочитаю разрешать либо сообщение со всеми параметрами в теле, либо GET со всеми параметрами на url-адресе и явно игнорировать параметры url с любым запросом POST. Это позволяет избежать путаницы.


Я бы подумал, что все еще может быть довольно спокойно иметь аргументы запроса, которые идентифицируют ресурс по URL, сохраняя полезную нагрузку контента, ограниченную телом POST. Это, казалось бы, отделяет соображения "что я посылаю?"против "кому я его посылаю?".


на остальное у camp есть некоторые руководящие принципы, которые мы можем использовать для стандартизации способа использования HTTP-глаголов. Это полезно при создании RESTful API, как вы делаете.

в двух словах: GET должен быть только для чтения, т. е. не влияет на состояние сервера. POST используется для создания ресурса на сервере. PUT используется для обновления или создания ресурса. DELETE используется для удаления ресурса.

другими словами, если ваше действие API изменяет состояние сервера, отдыхайте советует использовать POST/PUT / DELETE, но не GET.

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

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


Я согласен-вероятно, безопаснее использовать запрос GET, если вы просто передаете данные в URL, а не в теле. См.этот же вопрос для некоторых дополнительных представлений по всей концепции POST + GET.