HTTP GET su užklausos įstaiga

Mūsų programai sukuriu naują „RESTful“ interneto paslaugą.

Kai atliekami GET tam tikriems objektams, klientai gali paprašyti objekto turinio. Jei jie nori pridėti kai kuriuos parametrus (pavyzdžiui, surūšiuoti sąrašą), jie gali pridėti šiuos parametrus į užklausos eilutę.

Arba noriu, kad žmonės nurodytų šiuos parametrus užklausos įstaigoje. HTTP / 1.1 tai aiškiai nedraudžia. Tai leis jiems nurodyti daugiau informacijos, gali supaprastinti sudėtingų XML užklausų apibrėžimą.

Mano klausimai yra:

  • Ar tai gera idėja?
  • Ar „HTTP“ klientams kyla problemų naudojant užklausų įstaigas GET užklausoje?

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

1571 m
10 июня '09 в 23:47 2009-06-10 23:47 Evertas nustatytas birželio 10 d., 09:23, 23:47 2009-06-10 23:47
@ 18 atsakymų

Roy Fielding komentaras apie kūno įtraukimą į GET užklausą .

Taip Kitaip tariant, bet kuriame HTTP užklausos pranešime gali būti pranešimo kūnas ir todėl turi tai analizuoti. Tačiau GET serverio semantika yra ribota, kad kūnas, jei jis yra, neturi semantinės užklausos reikšmės. Reikalavimai analizavimui yra atskirti nuo metodo semantikos reikalavimų.

Taigi, taip, galite siųsti kūną su GET, ir ne, tai niekada nėra naudinga.

Tai dalis HTTP / 1.1 sluoksniuotos struktūros, kuri vėl bus aiški po to, kai specifikacija bus padalyta (nebaigtas darbas).

.... Roy

Taip, galite siųsti užklausos įstaigą naudodamiesi GET, bet jis neturėtų turėti jokios reikšmės. Jei suteikiate jam vertę analizuodami jį serveryje ir pakeisdami savo atsakymą pagal jo turinį, jūs ignoruojate šią rekomendaciją HTTP / 1.1 specifikacijoje, 4.3 skirsnyje :

[...] jei užklausos metodas neapima konkretaus objekto kūno semantikos, tada apdorojant užklausą, pranešimas turi būti ignoruojamas.

GET metodo aprašymas HTTP / 1.1 specifikacijoje, 9.3 skyrius :

GET metodas - bet kokios užklausos URI identifikuotos informacijos ([...]) išgavimas.

kuriame teigiama, kad užklausos įstaiga nėra išteklių identifikavimo dalis GET užklausoje, bet tik prašymo URI.

RFC2616“ atnaujinimas , vadinamas „HTTP / 1.1 spec“, yra pasenęs. 2014 m. Jis buvo pakeistas RFC 7230-7237. Citata „pranešimo kūnas turi būti ignoruojamas apdorojant užklausą“ buvo pašalintas. Dabar jis tiesiog „Prašo, kad pranešimų formavimas nepriklausytų nuo metodo semantikos, net jei metodas neapibrėžia jokio pranešimo kūno naudojimo.“ Antra citata: „GET metodas reiškia, kad bet kokia užklausos-URI identifikuota informacija yra pašalinta“ - iš komentaro

1313
11 июня '09 в 23:27 2009-06-11 23:27 atsakymą pateikė Paulius Morganas birželio 11 d., 09:27, 2009-06-11 23:27

Tol, kol galite tai padaryti, nes tai nėra aiškiai uždrausta HTTP specifikacijoje, siūlau vengti to paprasčiausiai todėl, kad žmonės nesitiki, kad kažkas veiks taip. HTTP užklausų grandinėje yra daug fazių, ir nors jie „dažniausiai“ atitinka HTTP specifikaciją, vienintelis dalykas, kurį esate tikras, yra tai, kad jie elgsis tradiciškai naudodami žiniatinklio naršykles. (Aš galvoju apie tokius dalykus kaip skaidrūs proxy, greitintuvai, A / V įrankiai ir tt)

Ši dvasia yra kietumo principas apie „liberalų, ką jūs sutinkate, ir konservatyvus tai, ką siunčiate“, noriu lengvai pagrįsti specifikacijos ribas.

border=0

Tačiau, jei turite gerų priežasčių, eikite į jį.

243
10 июня '09 в 23:53 2009-06-10 23:53 atsakymas pateikiamas birželio 10 d., 09:23 , 23:53, 2009-06-10 23:53

Tikriausiai susidursite su problemomis, jei bandysite naudoti talpyklą. Tarpininkas nenagrinėja GET įstaigos, kad pamatytų, ar parametrai turi įtakos atsakymui.

123
11 июня '09 в 0:10 2009-06-11 00:10 atsakymas pateikiamas Darrel Miller birželio 11 d., 09:10, 2009-06-11 00:10

Nei restliudentas, nei REST plokštė nepalaiko šio, bet garbanojimo.

HTTP specifikacija sako 4.3 skyriuje

Pranešimo įstaiga NEĮSKAIČIUOTŲ į užklausą, jei prašymo metodo specifikacija (5.1.1 skirsnis) neleidžia siuntimo objekto kūnui išsiųsti.

5.1.1 skirsnis nukreipia mus į 9.x skirsnį įvairiems metodams. Nė vienas iš jų aiškiai nedraudžia įtraukti pranešimo įstaigos. Tačiau ...

5.2 skirsnyje sakoma

Tikslus išteklius, identifikuojamas pagal interneto užklausą, nustatomas nagrinėjant lauką „Prašymas-URI“ ir „Priimančioji antraštė“.

ir 9.3 skirsnyje sakoma

GET metodas reiškia gauti bet kokią informaciją (objekto formą), nurodytą užklausos-URI.

Mes kartu darome prielaidą, kad apdorojant GET užklausą serveris neprivalo tikrinti nieko, išskyrus užklausos-URI ir priimančiosios antraštės laukus.

Taigi, HTTP specifikacija netrukdo siųsti žinutės kūno su GET, tačiau yra pakankamai dviprasmiškumo, kad manęs nenuostabu, jei jį nepalaiko visi serveriai.

62
27 марта '13 в 13:41 2013-03-27 13:41 atsakymą pateikė Dave Durbin kovo 13 d. 13:41 2013-03-27 13:41

Elasticsearch priima GET užklausas su kūnu. Atrodo, kad tai yra pageidaujamas variantas: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/common-options.html#_request_body_in_query_string

Kai kurios klientų bibliotekos (pvz., „Ruby“ tvarkyklė) gali parašyti „Cry“ komandą į stdout projektavimo režimu ir plačiai naudoti šią sintaksę.

39
03 дек. Atsakymas pateikiamas 03 d. 2013-12-03 14:15 '13, 14:15, 2013-12-03 14:15

Tai, ką bandote pasiekti, jau seniai buvo daroma daug dažniau, o tai, kas nėra naudinga naudingajam kroviniui, naudojant GET.

Jūs galite tiesiog sukurti savo specifinę paieškos rūšį arba, jei norite būti labiau atkuriamas, naudokite kažką panašaus į „OpenSearch“ ir POST užklausą URI, kuriam serveris davė komandą, pasakyti / atlikite paiešką. Tada serveris gali generuoti paieškos rezultatą arba sukurti galutinį URI ir peradresuoti naudojant 303.

Tai turi pranašumą, nes jis atitinka tradicinį PRG metodą, padeda grynųjų pinigų tarpininkams talpinti rezultatus ir pan.

Tačiau URI bet kuriuo atveju yra užkoduotas tam, kas nėra ASCII, o taip pat programa / x-www-form-urlencoded ir multipart / form-data. Jei norite remti „ReSTful“ scenarijus, aš rekomenduočiau tai naudoti vietoj to, kad būtų sukurtas kitas pasirinktinis „Json“ formatas.

26
11 июня '09 в 1:47 2009-06-11 01:47 atsakymas pateikiamas SerialSeb birželio 11 '09, 1:47 2009-06-11 01:47

Kuris serveris jį ignoruos? - fijiaaronas, rugpjūčio 30 d. 12, 21:27

Pavyzdžiui, „ Google“ blogiau nei ignoruoja, ji mano, kad tai klaida !

Išbandykite save naudodami paprastą tinklelį:

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

(1234 turinį seka CR-LF, todėl tai tik 6 baitai)

ir gausite:

 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. 

Taip pat gausite 400 „Bing“, „Apple“ ir kt. Prašymų, kuriuos aptarnauja „AkamaiGhost“.

Todėl aš nenorėčiau naudoti GET užklausų su kūno esme.

22
30 июня '13 в 0:26 2013-06-30 00:26 atsakymą pateikė vartotojo941239 birželio 30 d. , 13:13 2013-06-30 00:26

GET galite nusiųsti su kūnu arba siųsti POST ir atsisakyti RESTish religiosity (tai ne taip blogai, prieš 5 metus buvo tik vienas šio tikėjimo narys - jo komentarai buvo susieti pirmiau).

Taip pat nepriimami dideli sprendimai, tačiau GET kūno siuntimas gali užkirsti kelią kai kurių klientų ir kai kurių serverių problemoms.

POST vykdymas gali būti trukdomas kai kuriose „RESTish“ sistemose.

„Julian Reschke“ pasiūlė pirmiau naudoti nestandartinę HTTP antraštę, pvz., „SEARCH“, kuris gali būti elegantiškas sprendimas, išskyrus tai, kad jis yra dar mažiau tikėtinas.

Galbūt labiausiai produktyvus bus klientų perkėlimas, kuris gali ir negali atlikti visų pirmiau minėtų dalykų.

Klientai, kurie negali siųsti GET su kūnu (kurį žinau):

  • XmlHTTPRequest Fiddler

Klientai, kurie gali siųsti GET su įstaiga:

  • dauguma naršyklių

Serveriai ir bibliotekos, kurios gali gauti kūną iš GET:

  • Apache
  • Php

Serveriai (ir proxy), kurie sumažina kūną iš GET:

21
31 авг. atsakymas pateikiamas fijiaarono rugpjūčio 31 d 2012-08-31 00:41 '12 - 0:41 2012-08-31 00:41

RFC 2616 4.3 skirsnio „Pranešimų kūnas“:

Serveris PRIVALO perskaityti ir persiųsti pranešimo tekstą bet kuriuo prašymu; jei užklausos metodas neapima konkretaus subjekto kūno semantikos, tada apdorojant užklausą, žinutės kūnas turi būti ignoruojamas.

Taigi, serveriai visada turėtų perskaityti bet kurį pateiktą užklausos korpusą iš tinklo (patikrinkite turinio ilgį arba perskaitykite suskaidytą kūną ir tt). Be to, įgaliotieji asmenys privalo kreiptis į bet kurią jų gautą prašymą. Tada, jei RFC nustato šio metodo kūno semantiką, serveris gali iš tikrųjų naudoti užklausos kūną generuodamas atsakymą. Tačiau, jei RFC neapibrėžia kūno semantikos, serveris turėtų jį ignoruoti.

Tai atitinka aukščiau minėtą „Fielding“ citatą.

9.3 skirsnyje „GET“ aprašomas GET metodo semantika ir jame nėra paminėtas prašymo elementas. Todėl serveris turėtų ignoruoti bet kurią užklausos instituciją, kurią gauna GET užklausa.

16
07 марта '14 в 0:44 2014-03-07 00:44 atsakymas suteikiamas izrikui „ Kovo 07 d. 14“ 0:44 2014-03-07 00:44

Aš uždaviau šį klausimą IETF HTTP darbo grupėje. Roy Fielding komentaras (http / 1.1 autorius 1998 m.) Buvo toks

„... įgyvendinimas bus nutrauktas, kad būtų atlikta kita, nei analizuojama ir atmesta ši įstaiga, jei gautas“,

RFC 7213 (HTTPbis) skaito:

„GET užklausos žinutėje esanti naudingoji apkrova neturi konkrečios semantikos“;

Dabar akivaizdu, kad buvo siekiama, kad semantinė reikšmė GET prašymo įstaigose būtų uždrausta, o tai reiškia, kad prašymo įstaiga negali būti naudojama rezultatui daryti.

Yra proxy serverių, kurie tikrai nutraukia jūsų užklausą įvairiais būdais, jei įtraukiate kūną į GET.

Taigi, trumpai tariant, nedarykite to.

13
28 июля '16 в 4:06 2016-07-28 04:06 atsakymą pateikė Adrien liepos 28 d., 16 d., 4:06 2016-07-28 04:06

Jei tikrai norite siųsti „Cacheable JSON / XML“ korpusą žiniatinklio programai, vienintelė protinga vieta jūsų duomenims įdėti yra užklausos eilutė, koduota naudojant RFC4648: Base 64 Kodavimas su URL ir saugi failų pavadinimų abėcėlė . Žinoma, galite tiesiog nustatyti urlencode JSON ir įdėti - į URL parametro vertę, bet Base64 duoda mažesnį rezultatą. Atminkite, kad yra URL dydžio apribojimai, žr. Kokia yra didžiausia URL trukmė skirtingose ​​naršyklėse? .

Galbūt manote, kad „Base64“ padding = simbolis gali būti blogas URL parametro reikšmei, tačiau atrodo, kad jis neteisingas - žr. Šią diskusiją: http://mail.python.org/pipermail/python-bugs-list/2007- Vasaris / 037195.html . Tačiau neturėtumėte įvesti užkoduotų duomenų be param vardo, nes koduota eilutė bus interpretuojama kaip param raktas su tuščia verte. Ar galėčiau naudoti kažką panašaus ?_b64=<encodeddata> .

7
18 февр. gerto atsakymas, pateiktas vasario 18 d. 2013-02-18 16:43 '13, 16:43, 2013-02-18 16:43

Mane nusiminusi, kad REST yra todėl, kad protokolas nepalaiko OOP, o Get metodas yra įrodymas. Kaip sprendimą, galite serializuoti DTO į JSON ir tada sukurti užklausos eilutę. Serverio pusėje galite deserialiuoti užklausos eilutę DTO.

Pažvelkite:

Pranešimu pagrįstas požiūris gali padėti išspręsti „Get“ metodo suvaržymą. Galite siųsti bet kokią DTO kaip ir užklausos įstaigai.

Interneto paslaugos Nelibur struktūra suteikia funkcionalumą, kurį galite naudoti

 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> 
5
10 февр. GSerjo atsakymas 10 vasario mėn. 2014-02-10 02:04 '14 at 2:04 2014-02-10 02:04

Pagal XMLHttpRequest, tai neteisinga. Iš standarto :

4.5.6 Siuntimo send() metodas

 client . send([ body = null]) 

Pradeda užklausą. Neprivalomas argumentas pateikia užklausos pagrindą. Argumentas ignoruojamas, jei užklausos metodas yra GET arba HEAD .

InvalidStateError išimtis InvalidStateError jei būsena nėra atidaryta arba yra nustatyta send() vėliava.

send( body ) metodas turėtų atlikti šiuos veiksmus:

  1. Jei būsena nėra atidaryta, InvalidStateError išimtis.
  2. Jei nustatyta send() vėliava, InvalidStateError išimtis.
  3. Jei užklausos metodas yra GET arba HEAD , nustatykite kūno nulį.
  4. Jei kūnas tuščias, pereikite prie kito žingsnio.

Nors nemanau, kad tai turėtų būti, nes GET užklausai gali prireikti daug turinio.

Taigi, jei naudojate naršyklės XMLHttpRequest užklausą, greičiausiai jis neveiks.

5
04 мая '16 в 23:07 2016-05-04 23:07 Atsakymą pateikė Rafael Sales gegužės 4 d. 16 d. 23:07 2016-05-04 23:07

Kaip apie nenuoseklius bazinius64 koduotus antraštes? „SOMETHINGAPP pavadinimai: sdfSD45fdg45 / SOS“

Ilgio hm apribojimai. Ar galite atlikti POST apdorojimą, kad atskirtumėte vertes? Jei jums reikia paprastų parametrų, pvz., Rūšiavimo, nesuprantu, kodėl tai būtų problema. Esu tikras, kad esate susirūpinęs.

4
16 февр. atsakymas chaz 16 vas . 2011-02-16 00:34 '11 prie 0:34 2011-02-16 00:34

Pavyzdžiui, jis veikia su Curl, Apache ir PHP.

PHP failas:

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

Konsolės komanda:

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

Išvada:

 GET {"the": "body"} 
4
21 нояб. atsakymas pateikiamas mnv . 2015-11-21 01:16 '15 - 1:16 2015-11-21 01:16

IMHO, galite tiesiog nusiųsti JSON koduotą (ty encodeURIComponent ) į URL , taigi jūs nepažeidžiate HTTP specifikacijų ir negavote JSON į serverį.

4
26 февр. Atsakymas pateikiamas EthraZa 26 vasario mėn. 2013-02-26 22:04 '13, 10:04 PM 2013-02-26 22:04

Nerekomenduočiau, tai prieštarauja standartinei praktikai ir nepateikia to. Norite išsaugoti kūno turinį, o ne parametrus.

3
10 июня '09 в 23:56 2009-06-10 23:56 atsakymas pateikiamas debesies viršūnėje, birželio 10 d. , 09:56, 2009-06-10 23:56

Atrodo, kad „Google“, „IBM“, „Microsoft“ ir „apigee“ naudoja pavadinimą, nurodydamos tikrai tikėtiną metodą, panašų į „X-HTTP-Method-Override“: GET.
Pagal minėtą dienoraštį, tai įrašoma į POST kaip PUT formą.
Manau, kad šis sprendimas gali būti naudojamas šioje problemoje.

Kitaip tariant, manau, kad POST su X-HTTP-Override metodu: GET antraštė yra geriausias sprendimas.

0
26 окт. atsakymas duotas tabata Spalio 26 d 2016-10-26 05:25 '16 at 5:25 am 2016-10-26 05:25

Kiti klausimai apie žymes arba Užduoti klausimą