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.

19voto

user941239 Punkte 769

Welcher Server wird sie ignorieren? - fijiaaron 30. Aug '12 um 21:27

Google Wenn sie zum Beispiel etwas Schlimmeres tut, als es zu ignorieren, wird sie es als ein Fehler ¡!

Probieren Sie es selbst mit einem einfachen netcat:

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

1234

(auf den Inhalt von 1234 folgt CR-LF, also insgesamt 6 Bytes)

und Sie werden es bekommen:

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.

Sie erhalten auch 400 Bad Request von Bing, Apple, etc... die von AkamaiGhost bedient werden.

Daher würde ich von der Verwendung von GET-Anfragen mit einer Body-Entität abraten.

16voto

Rafael Sales Punkte 318

Laut XMLHttpRequest ist sie nicht gültig. Von der [Standard](https://xhr.spec.whatwg.org/#the-send()-method) :

4.5.6 Die send() méthode

client . send([body = null])

Initiiert die Anfrage. Das optionale Argument liefert den Request Körper. Das Argument wird ignoriert, wenn die Anfragemethode GET ou HEAD .

Wirft ein InvalidStateError Ausnahme, wenn einer der beiden Zustände nicht geöffnet oder die send() Flagge gesetzt ist.

Le site send(_body_) Methode müssen diese Schritte ausgeführt werden:

  1. Wenn der Zustand nicht geöffnet werfen ein InvalidStateError Ausnahme.
  2. Wenn die send() Flag gesetzt ist, wird ein InvalidStateError Ausnahme.
  3. Wenn die Anfragemethode GET ou HEAD gesetzt Körper auf Null.
  4. Si Körper Null ist, gehen Sie zum nächsten Schritt.

Obwohl, ich glaube nicht, dass es sollte, weil GET-Anfrage könnte große Körper Inhalt benötigen.

Wenn Sie sich also auf XMLHttpRequest eines Browsers verlassen, ist es wahrscheinlich, dass es nicht funktionieren wird.

11voto

gertas Punkte 16291

Wenn Sie wirklich einen cachbaren JSON/XML-Body an die Webanwendung senden wollen, ist der einzige vernünftige Ort, um Ihre Daten in einen Query-String zu setzen, der mit RFC4648: Base 64-Kodierung mit URL- und Dateinamen-Safe-Alphabet . Natürlich könnte man JSON einfach urlencodieren und in den Wert des URL-Parameters einfügen, aber Base64 liefert ein kleineres Ergebnis. Denken Sie daran, dass es Einschränkungen für die URL-Größe gibt, siehe Was ist die maximale Länge einer URL in verschiedenen Browsern? .

Sie denken vielleicht, dass Base64's padding = Zeichen kann schlecht für URL's param Wert sein, aber es scheint nicht - siehe diese Diskussion: http://mail.python.org/pipermail/python-bugs-list/2007-February/037195.html . Sie sollten jedoch keine kodierten Daten ohne Parameternamen angeben, da eine kodierte Zeichenkette mit Füllung als Parameterschlüssel mit leerem Wert interpretiert wird. Ich würde etwas verwenden wie ?_b64=<encodeddata> .

10voto

Xenonite Punkte 1563

Sie haben eine Liste von Optionen, die weitaus besser sind als die Verwendung eines Request Body mit GET.

Nehmen wir an, Sie haben Kategorien und Artikel für jede Kategorie. Beide sollen durch eine ID identifiziert werden ("catid" / "itemid" für dieses Beispiel). Sie wollen nach einem anderen Parameter "sortby" in einer bestimmten "Reihenfolge" sortieren. Sie möchten Parameter für "sortby" und "order" übergeben:

Sie können:

  1. Verwenden Sie Abfragezeichenfolgen, z. B. example.com/category/{catid}/item/{itemid}?sortby=itemname&order=asc
  2. Verwenden Sie mod_rewrite (oder ähnliches) für Pfade: example.com/category/{catid}/item/{itemid}/{sortby}/{order}
  3. Verwenden Sie einzelne HTTP-Header, die Sie mit der Anfrage übergeben
  4. Verwenden Sie eine andere Methode, z. B. POST, um eine Ressource abzurufen.

Alle haben ihre Nachteile, sind aber weitaus besser als die Verwendung eines GET mit einem Körper.

10voto

cloudhead Punkte 15075

Ich würde davon abraten, denn es widerspricht den üblichen Praktiken und bietet keine große Gegenleistung. Sie wollen den Körper für den Inhalt behalten, nicht für Optionen.

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