HTTP GET with request body

Rozwijam nowy serwis internetowy dla naszej aplikacji.

Podczas wykonywania GET na niektórych podmiotach, klienci mogą zażądać zawartości podmiotu. Jeśli chcą dodać jakieś parametry (na przykład sortowanie listy), mogą dodać te parametry w łańcuchu zapytania.

Alternatywnie chcę, aby ludzie mogli określić te parametry w ciele żądania. HTTP / 1.1 nie wydaje się wyraźnie zabraniać tego. To pozwoli im określić więcej informacji, może Ułatw określanie złożonych żądań XML.

Moje pytania:

    Czy to dobry pomysł?
  • Czy klienci HTTP będą mieli problemy z używaniem ciał żądań w żądaniu GET?

Http://tools.ietf.org/html/rfc2616

 1479
Author: K48, 2009-06-11

17 answers

Komentarz Roya Fieldinga na temat włączenia ciała z żądaniem GET .

Tak. Innymi słowy, każda wiadomość żądania HTTP może zawierać ciało wiadomości, a zatem musi analizować wiadomości z myślą o tym. Semantyka serwera dla GET jest jednak ograniczona tak, że ciało, jeśli w ogóle, nie ma znaczenia semantycznego dla żądania. Wymagania podczas parsowania są oddzielone od wymagań dotyczących semantyki metod.

Więc tak, możesz wysłać ciało z GET, i nie, to nigdy nie jest przydatne aby to zrobić.

Jest to część warstwowego projektu HTTP / 1.1, który stanie się Wyczyść ponownie po podzieleniu specyfikacji (praca w toku).

....Roy

Tak, możesz wysłać ciało żądania za pomocą GET, ale nie powinno ono mieć żadnego znaczenia. Jeśli nadasz jej znaczenie, analizując ją na serwerze i zmieniając odpowiedź na podstawie jej zawartości , ignorujesz to zalecenie w sekcji Specyfikacja HTTP/1.1 4.3:

[...] jeżeli metoda żądania nie zawiera zdefiniowanej semantyki dla podmiotu-ciała, wtedy message-body powinno być ignorowane podczas obsługi żądania.

Oraz opis metody GET w w sekcji HTTP/1.1 spec 9.3:

Metoda GET oznacza pobieranie wszelkich informacji ([...]) jest identyfikowany przez Request-URI.

Który stwierdza, że request-body nie jest częścią identyfikacja zasobu w żądaniu GET, tylko URI żądania.

 1252
Author: Paul Morgan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-18 18:18:29

Podczas gdy ty możesz to zrobić, o ile nie jest to wyraźnie wykluczone przez specyfikację HTTP, sugerowałbym unikanie tego po prostu dlatego, że ludzie nie oczekują, że rzeczy będą działać w ten sposób. Istnieje wiele faz w łańcuchu żądań HTTP i chociaż" głównie " są one zgodne ze specyfikacją HTTP, jedyną rzeczą, którą masz pewność, jest to, że będą zachowywać się tak, jak tradycyjnie używane przez przeglądarki internetowe. (Myślę o takich rzeczach jak przezroczyste proxy, akceleratory, Zestawy Narzędzi A / V itp.)

To jest duch stojący za zasadą solidności z grubsza "bądź liberalny w tym, co akceptujesz, i konserwatywny w tym, co wysyłasz", nie chcesz przesuwać granic specyfikacji bez ważnego powodu.

Jednak, jeśli masz dobry powód, idź do niego.

 240
Author: caskey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-10 20:53:43

Prawdopodobnie napotkasz problemy, jeśli kiedykolwiek spróbujesz skorzystać z buforowania. Proxy nie będą szukać w ciele GET, aby sprawdzić, czy parametry mają wpływ na odpowiedź.

 120
Author: Darrel Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-10 21:10:50

Ani restclient ani REST console nie obsługują tego, ale curl tak.

Specyfikacja HTTP mówi w sekcji 4.3

Wiadomość-body nie może być dołączona do żądania, jeżeli Specyfikacja metody żądania (sekcja 5.1.1) nie pozwala na wysyłanie entity-body w żądaniach.

Sekcja 5.1.1 przekierowuje nas do sekcji 9.x dla różnych metod. Żaden z nich wyraźnie nie zabrania umieszczania treści wiadomości. Jednak...

Sekcja 5.2 mówi

Dokładny zasób zidentyfikowany przez żądanie internetowe jest określany przez sprawdzenie zarówno Request-URI, jak i pola nagłówka hosta.

I sekcja 9.3 mówi

Metoda GET oznacza pobieranie wszelkich informacji (w postaci encji) zidentyfikowanych przez Request-URI.

Które razem sugerują, że podczas przetwarzania żądania GET, serwer nie jest wymagany do sprawdź Wszystko inne niż pole Request-URI i nagłówek hosta.

Podsumowując, Specyfikacja HTTP nie uniemożliwia wysyłania wiadomości-body Z GET, ale jest wystarczająca dwuznaczność, że nie zdziwiłoby mnie, gdyby nie była obsługiwana przez wszystkie serwery.

 62
Author: Dave Durbin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-27 10:41:38

Elasticsearch akceptuje żądania GET z ciałem. Wydaje się nawet, że jest to preferowany sposób : http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/common-options.html#_request_body_in_query_string

Niektóre biblioteki klienckie (jak sterownik Ruby) mogą zalogować polecenie cry na stdout w trybie deweloperskim i używa tej składni w znacznym stopniu.

 37
Author: jlecour,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-03 11:15:20

To, co próbujesz osiągnąć, zostało zrobione przez długi czas za pomocą znacznie bardziej popularnej metody, która nie polega na użyciu ładunku z GET.

Możesz po prostu zbudować swój konkretny typ mediatype wyszukiwania, lub jeśli chcesz być bardziej spokojny, użyj czegoś takiego jak OpenSearch i wyślij żądanie do URI serwera polecony, powiedzmy / search. Serwer może następnie wygenerować wynik wyszukiwania lub zbudować ostateczny URI i przekierować za pomocą 303.

To ma tę zaletę, że tradycyjna metoda PRG, pomaga pośrednikom cache buforować wyniki itp.

To powiedziawszy, URI są zakodowane dla wszystkiego, co nie jest ASCII, podobnie jak application/x-www-form-urlencoded i multipart / form-data. Zalecałbym używanie tego, a nie tworzenie kolejnego niestandardowego formatu json, jeśli twoim zamiarem jest obsługa scenariuszy ReSTful.

 25
Author: SerialSeb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-23 08:44:41

Który serwer to zignoruje? - fijiaaron Sie 30 '12 at 21: 27

Google na przykład robi gorzej niż ignorowanie go, uzna to za błąd !

Spróbuj sam z prostym netcatem:

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

1234

(Po treści 1234 następuje CR-LF, czyli w sumie 6 bajtów)

A otrzymasz:

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.

Otrzymujesz również 400 złych żądań od Bing, Apple itp... które są obsługiwane przez AkamaiGhost.

Więc nie doradzamy korzystanie z żądań GET z jednostką organizacyjną.

 23
Author: user941239,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-29 21:26:20

Możesz albo wysłać GET z ciałem, albo wysłać POST i porzucić religijność (nie jest tak źle, 5 lat temu był tylko jeden członek tej wiary - jego komentarze podlinkowane powyżej).

Nie są to dobre decyzje, ale wysłanie ciała GET może zapobiec problemom dla niektórych klientów -- i niektórych serwerów.

Robienie posta może mieć przeszkody z niektórymi frameworkami.

Julian Reschke zasugerował powyżej użycie niestandardowego nagłówka HTTP, takiego jak "SEARCH", które może być eleganckie rozwiązanie, poza tym, że jest jeszcze mniej prawdopodobne, że będzie obsługiwane.

Najbardziej produktywne może być lista klientów, którzy mogą i nie mogą wykonać każdego z powyższych zadań.

Klienci, którzy nie mogą wysłać GET Z body (o którym wiem):

  • XMLHttpRequest

Klienci, którzy mogą wysłać GET Z body:

  • większość przeglądarek

Serwery i biblioteki, które mogą pobierać ciało z GET:

  • Apache
  • PHP

Serwery (i proxy) które usuwają body Z GET:

  • ?
 22
Author: fijiaaron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-30 21:48:49

From RFC 2616, section 4.3 , "Message Body":

Serwer powinien odczytać i przesłać treść wiadomości na każde żądanie; jeśli metoda request nie obejmuje zdefiniowanej semantyki dla podmiotu-organu, wtedy message-body powinno być ignorowane podczas obsługi żądania.

Oznacza to, że serwery powinny zawsze odczytywać treść dostarczonego żądania z sieci (sprawdzić Długość zawartości lub odczytać masywną treść, itp.). Ponadto, proxy powinny przesłać każdy taki organ żądający ich odbiór. Następnie, jeśli RFC definiuje semantykę dla ciała dla danej metody, serwer może faktycznie użyć ciała żądania do wygenerowania odpowiedzi. Jeśli jednak RFC nie definiuje semantyki dla ciała, to serwer powinien ją zignorować.

Jest to zgodne z cytatem z Fielding powyżej.

Sekcja 9.3 , "GET", opisuje semantykę metody GET i nie wspomina o ciałach żądań. Dlatego serwer powinien ignorować wszelkie ciało żądania otrzymuje na żądanie GET.

 16
Author: izrik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-06 21:44:45

Zadałem to pytanie do IETF HTTP WG. Komentarz Roya Fieldinga (autora dokumentu http / 1.1 z 1998 roku) był taki, że

"... implementacja zostanie przerwana, aby zrobić coś innego niż analiza i odrzucenie tego ciała, jeśli zostanie odebrana "

RFC 7213 (HTTPbis) stwierdza:

"ładunek w wiadomości żądania GET nie ma zdefiniowanej semantyki;"

Wydaje się teraz jasne, że intencją było, aby znaczenie semantyczne na ciałach żądania GET było zabronione, co oznacza, że organ żądający nie może być użyty do wpływania na wynik.

Istnieją proxy, które zdecydowanie złamają Twoją prośbę na różne sposoby, jeśli dołączysz ciało do GET.

Więc podsumowując, nie rób tego.

 13
Author: Adrien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-20 03:21:37

Jeśli naprawdę chcesz wysłać cachable JSON / XML body do aplikacji webowej, jedynym rozsądnym miejscem do umieszczenia Twoich danych jest łańcuch zapytań zakodowany RFC4648: Base 64 kodowanie z adresem URL i nazwą Pliku Bezpieczny Alfabet. Oczywiście możesz po prostu urlencode JSON i put jest w wartości URL param, ale Base64 daje mniejszy wynik. Należy pamiętać, że istnieją ograniczenia rozmiaru adresu URL, zobacz Jaka jest maksymalna długość adresu URL w różnych przeglądarkach? .

Możesz pomyśleć, że Base64 ' s padding = znak może być zły dla wartości param URL, jednak wydaje się, że nie - patrz dyskusja: http://mail.python.org/pipermail/python-bugs-list/2007-February/037195.html . Nie należy jednak umieszczać zakodowanych danych bez nazwy param, ponieważ zakodowany łańcuch z wypełnieniem zostanie zinterpretowany jako klucz param z pustą wartością. Użyłbym czegoś takiego jak ?_b64=<encodeddata>.

 7
Author: gertas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:54

Jestem zdenerwowany, że REST as protokół nie obsługuje OOP i Get metoda jest dowodem. Jako rozwiązanie możesz serializować swoje DTO do JSON, a następnie utworzyć ciąg zapytania. Po stronie serwera możesz deserializować ciąg zapytania do DTO.

Spójrz na:

Podejście oparte na wiadomościach może pomóc rozwiązać ograniczenie metody Get. Możesz wysłać dowolne DTO tak jak w request body

Nelibur Web service framework zapewnia funkcjonalność, z której można korzystać

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
 5
Author: GSerjo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-10 09:07:56

A co z niezgodnymi nagłówkami zakodowanymi w base64? "SOMETHINGAPP-PARAMS: sdfSD45fdg45 / aS"

Ograniczenia długości hm. Nie możesz sprawić, by Obsługa postów rozróżniała znaczenia? Jeśli chcesz prostych parametrów, takich jak sortowanie, nie rozumiem, dlaczego miałby to być problem. Myślę, że to pewność, o którą się martwisz.

 4
Author: chaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-15 21:34:57

IMHO możesz po prostu wysłać JSON zakodowany (tj. encodeURIComponent) w URL, w ten sposób nie naruszasz specyfikacji HTTP i dostajesz JSON Na serwer.

 4
Author: EthraZa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-27 19:18:59

Zgodnie z XMLHttpRequest, to nie jest poprawne. Ze standardu :

4.5.6 Metoda send()

client . send([body = null])

Inicjuje żądanie. Opcjonalny argument dostarcza żądanie ciało. Argument jest ignorowany, jeśli metoda żądania to GET lub HEAD.

Rzuca InvalidStateError wyjątek, jeśli któreś ze Stanów nie jest otwarty lub ustawiony jest znacznik send().

Metoda send(body) musi wykonać następujące kroki:

  1. jeśli stan nie jest otwarty, wyrzuć wyjątek InvalidStateError.
  2. jeśli flaga send() jest ustawiona, rzuć wyjątek InvalidStateError.
  3. Jeśli metoda żądania to GET lub HEAD, Ustaw body NA null.
  4. Jeśli ciało jest równe null, przejdź do następnego kroku.

Chociaż myślę, że nie powinno, ponieważ żądanie GET może wymagać dużej zawartości ciała.

Więc, jeśli polegasz na XMLHttpRequest przeglądarki, prawdopodobnie nie będzie działać.

 4
Author: Rafael Sales,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-04 20:51:46

Nie radziłbym tego, jest to sprzeczne ze standardowymi praktykami i nie oferuje tyle w zamian. Chcesz zachować treść, a nie Opcje.

 3
Author: cloudhead,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-10 20:56:09

Na przykład, działa z Curl, Apache i PHP.

Plik PHP:

<?php
echo $_SERVER['REQUEST_METHOD'] . PHP_EOL;
echo file_get_contents('php://input') . PHP_EOL;

Polecenie konsoli:

$ curl -X GET -H "Content-Type: application/json" -d '{"the": "body"}' 'http://localhost/test/get.php'

Wyjście:

GET
{"the": "body"}
 3
Author: mnv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-20 22:16:01