3157 Stimmen

HTTP GET mit Anfragekörper

Ich entwickle gerade einen neuen RESTful Webservice für unsere Anwendung.

Bei einem GET auf bestimmte Entitäten können Clients den Inhalt der Entität anfordern. Wenn sie einige Parameter hinzufügen möchten (z. B. Sortieren einer Liste), können sie diese Parameter in den Abfrage-String einfügen.

Alternativ möchte ich, dass die Benutzer diese Parameter im Anfragetext angeben können. HTTP/1.1 scheint dies nicht ausdrücklich zu verbieten. Dadurch können sie mehr Informationen angeben, was die Angabe komplexer XML-Anfragen erleichtern könnte.

Meine Fragen:

  • Ist das überhaupt eine gute Idee?
  • Werden HTTP-Clients Probleme mit der Verwendung von Request Bodies innerhalb einer GET-Anfrage haben?

https://www.rfc-editor.org/rfc/rfc2616

620 Stimmen

Der Vorteil besteht darin, dass XML- oder JSON-Anfragekörper problemlos gesendet werden können, es gibt keine Längenbeschränkung und sie sind einfacher zu kodieren (UTF-8).

39 Stimmen

Wenn Sie eine sichere und idempotente Methode suchen, die Anfragekörper erlaubt, sollten Sie sich SEARCH, PROPFIND und REPORT ansehen. Wenn Sie GET nicht verwenden und einen Anfragebody haben, wird das Caching natürlich mehr oder weniger zunichte gemacht.

3 Stimmen

Unabhängig davon, ob die Spezifikation dies zulässt, verstößt es gegen den Geist von REST.

93voto

Dave Durbin Punkte 3480

Weder restclient ni REST-Konsole unterstützt dies, aber curl schon.

Le site HTTP-Spezifikation heißt es in Abschnitt 4.3

Ein Message-Body MUSS NICHT in einer Anfrage enthalten sein, wenn die Spezifikation der Anfragemethode (Abschnitt 5.1.1) das Senden eines Entity-Bodys in Anfragen nicht zulässt.

Abschnitt 5.1.1 leitet uns zu Abschnitt 9.x für die verschiedenen Methoden weiter. Keine von ihnen verbietet ausdrücklich die Aufnahme eines Nachrichtenkörpers. Allerdings...

Abschnitt 5.2 sagt

Die genaue Ressource, die durch eine Internet-Anfrage identifiziert wird, wird durch Untersuchung der Request-URI und des Host-Header-Feldes bestimmt.

et Abschnitt 9.3 sagt

Die GET-Methode bedeutet, dass alle Informationen (in Form einer Entität) abgerufen werden, die durch die Request-URI identifiziert werden.

Zusammengenommen bedeutet dies, dass ein Server bei der Bearbeitung einer GET-Anfrage nicht erforderlich um etwas anderes als die Request-URI und das Host-Header-Feld zu untersuchen.

Zusammenfassend lässt sich sagen, dass die HTTP-Spezifikationen nicht verhindern, dass ein Message-Body mit GET gesendet wird, aber es gibt genügend Unklarheiten, dass es mich nicht überraschen würde, wenn dies nicht von allen Servern unterstützt wird.

45voto

Adrien Punkte 995

Ich habe diese Frage an die IETF HTTP WG gestellt. Der Kommentar von Roy Fielding (Autor des http/1.1-Dokuments von 1998) lautete, dass

"... eine Implementierung würde nicht funktionieren, wenn sie etwas anderes tun würde, als diesen Körper zu analysieren und zu verwerfen, wenn er empfangen wird.

RFC 7213 (HTTPbis) besagt:

"Eine Nutzlast innerhalb einer GET-Anforderungsnachricht hat keine definierte Semantik;"

Es scheint nun klar zu sein, dass die semantische Bedeutung von GET-Anfragekörpern verboten ist, was bedeutet, dass der Anfragekörper nicht verwendet werden kann, um das Ergebnis zu beeinflussen.

Es gibt Proxys, die Folgendes tun definitiv Ihre Anfrage auf verschiedene Weise unterbrechen, wenn Sie bei GET einen Body einfügen.

Kurzum: Tun Sie es nicht.

42voto

SerialSeb Punkte 6618

Das, was Sie erreichen wollen, wird schon seit langem mit einer weitaus gängigeren Methode durchgeführt, die nicht auf der Verwendung einer Nutzlast mit GET beruht.

Sie können einfach Ihren eigenen Medientyp für die Suche erstellen, oder, wenn Sie mehr RESTful sein wollen, etwas wie OpenSearch verwenden und die Anfrage an den vom Server angewiesenen URI, z. B. /search, posten. Der Server kann dann das Suchergebnis generieren oder den endgültigen URI erstellen und die Anfrage mit einer 303 weiterleiten.

Dies hat den Vorteil, dass es der traditionellen PRG-Methode folgt und den Cache-Zwischenspeichern hilft, die Ergebnisse zwischenzuspeichern usw.

Abgesehen davon sind URIs ohnehin für alles, was nicht ASCII ist, kodiert, und das gilt auch für application/x-www-form-urlencoded und multipart/form-data. Ich würde empfehlen, dies zu verwenden, anstatt ein weiteres benutzerdefiniertes json-Format zu erstellen, wenn Sie beabsichtigen, ReSTful-Szenarien zu unterstützen.

42voto

fijiaaron Punkte 4664

Sie können entweder einen GET mit einem Body oder einen POST senden und die REST-Religiosität aufgeben (es ist nicht so schlimm, vor 5 Jahren gab es nur ein Mitglied dieses Glaubens - seine Kommentare sind oben verlinkt).

Beides sind keine guten Entscheidungen, aber das Senden eines GET-Bodys kann Probleme für einige Clients - und einige Server - verhindern.

POST kann bei einigen REST-Frameworks zu Problemen führen.

Julian Reschke schlug oben vor, einen Nicht-Standard-HTTP-Header wie "SEARCH" zu verwenden, was eine elegante Lösung sein könnte, nur ist es noch unwahrscheinlicher, dass sie unterstützt wird.

Am produktivsten dürfte es sein, die Kunden aufzulisten, die die oben genannten Aufgaben erfüllen können und die nicht.

Clients, die keinen GET mit Body senden können (soweit ich weiß):

  • XmlHTTPRequest Fiddler

Clients, die einen GET mit Body senden können:

  • die meisten Browser

Server und Bibliotheken, die einen Body von GET abrufen können:

  • Apache
  • PHP

Server (und Proxys), die einen Body von GET entfernen:

  • ?

25voto

izrik Punkte 838

Von RFC 2616, Abschnitt 4.3 , "Nachrichtentext":

Ein Server SOLLTE bei jeder Anfrage einen Message-Body lesen und weiterleiten; wenn die Anfragemethode keine definierte Semantik für einen Entity-Body enthält, dann SOLLTE der message-body bei der Bearbeitung der Anfrage ignoriert werden.

Das heißt, Server sollten immer jeden bereitgestellten Request Body aus dem Netz lesen (Content-Length prüfen oder einen Chunked Body lesen, etc.). Außerdem sollten Proxys jeden solchen Request Body, den sie erhalten, weiterleiten. Wenn der RFC eine Semantik für den Body für die gegebene Methode definiert, kann der Server den Request Body für die Generierung einer Antwort verwenden. Wenn jedoch der RFC nicht Semantik für den Body definieren, dann sollte der Server ihn ignorieren.

Dies steht im Einklang mit dem obigen Zitat von Fielding.

Abschnitt 9.3 GET", beschreibt die Semantik der GET-Methode und erwähnt keine Anfragebodies. Daher sollte ein Server jeden Request Body, den er bei einer GET-Anfrage erhält, ignorieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X