Taikymas / x-www-form-urlencoded arba multipart / form-data?

HTTP yra du būdai POST duomenims: application/x-www-form-urlencoded ir multipart/form-data . Suprantu, kad dauguma naršyklių gali įkelti failus tik tada, kai naudojami kelių multipart/form-data . Ar yra kokių nors papildomų gairių, kada naudoti vieną iš kodavimo tipų API kontekste (be dalyvavimo naršyklėje)? Tai gali būti, pavyzdžiui, remiantis:

  • duomenų dydis
  • ne ASCII simbolių
  • (nekoduotų) dvejetainių duomenų buvimas
  • reikia perduoti papildomus duomenis (pvz., failo pavadinimą)

Iš esmės neradau oficialių nurodymų internete dėl skirtingų tipų turinio naudojimo.

935
24 окт. nustatyti maks. 24 okt. 2010-10-24 14:12 '10, 14:12, 2010-10-24 14:12
@ 5 atsakymai

Tl; DR

Istorijos moralė yra ta, kad jei turite dvejetainius (ne raidinius ir skaitmeninius) duomenis (arba reikšmingą naudingąją apkrovą) perdavimui, naudokite multipart/form-data . Priešingu atveju naudokite application/x-www-form-urlencoded .


Aprašyti MIME tipai yra dvi Content-Type antraštės, skirtos HTTP POST užklausoms, kurias turi palaikyti vartotojų agentai (naršyklės). Abiejų šių užklausų tikslas yra atsiųsti serverio vardo / vertės porų sąrašą. Priklausomai nuo perduodamų duomenų tipo ir kiekio, vienas metodas bus efektyvesnis už kitą. Norėdami suprasti, kodėl, turite pamatyti, ką kiekvienas daro po viršeliais.

Taikant application/x-www-form-urlencoded , serveriui siunčiamo HTTP pranešimo kūnas iš esmės yra viena milžiniška užklausos eilutė - pavadinimo / vertės poros yra atskiriamos ir ( > ), o pavadinimai atskiriami nuo reikšmių lygiaverčiu simboliu ( = ). Pavyzdys gali būti:

MyVariableOne=ValueOne>

Pagal specifikaciją :

[Rezervuota ir] ne raidiniai skaitmeniniai simboliai pakeičiami žodžiais "% HH", procentinis ženklas ir du šešioliktainiai skaitmenys, vaizduojantys ASCII simbolių kodą

Tai reiškia, kad už kiekvieną ne raidinį ir skaitmeninį baitą, kuris egzistuoja vienoje iš mūsų vertybių, reikės atvaizduoti tris baitus. Dideliems dvejetainiams naudingosios apkrovos trigubinimas bus labai neefektyvus.

Tai apima multipart/form-data . Naudojant šį pavadinimo / vertės porų siuntimo būdą, kiekviena pora MIME pranešime yra pavaizduota kaip „dalis“ (kaip aprašyta kituose atsakymuose). Dalys atskiriamos konkrečia eilės riba (pasirinkta tiksliai taip, kad ši ribinė eilutė nenustatoma nė viename iš „naudingų“ krovinių). Kiekviena dalis turi savo MIME antraštių rinkinį, pvz., Content-Type , ypač Content-Disposition , kuris gali suteikti kiekvienai daliai „pavadinimą“. Kiekvienos vardo / vertės poros vertės elementas yra kiekvieno MIME pranešimo dalies naudingoji apkrova. MIME specifikacija suteikia mums daugiau galimybių, kai pateikiamos naudingosios apkrovos vertės - mes galime pasirinkti efektyviau koduoti dvejetainius duomenis, kad išsaugotume juostos plotį (pvz., Bazę 64 arba net dvigubą versiją).

Kodėl ne visą laiką naudoti multipart/form-data ? Trumpų raidinių ir skaitmeninių reikšmių (pvz., Daugelio žiniatinklio formų) pridėjimas, pridėjus visas MIME antraštes, yra didesnis už bet kokį efektyvesnį dvejetainį kodavimą.

1475
02 нояб. Atsakymą pateikė Matt Bridges 02.11. 2010-11-02 00:59 '10 ne 0:59 2010-11-02 00:59

SKAITYTI PIRMĄ PIRMĄ PIRMĄ!

Žinau, kad tai jau treji metai, tačiau Matto atsakymas (priimtas) yra neišsamus ir galiausiai sukels problemų. Svarbiausias dalykas yra tai, kad jei nuspręsite naudoti multipart/form-data , siena neturėtų būti rodoma duomenų rinkmenose, kurias serveris galutinai gauna.

Tai nėra problema dėl application/x-www-form-urlencoded , nes nėra sienos. x-www-form-urlencoded taip pat gali visada tvarkyti dvejetainius duomenis, paprasčiausiai pasukdami vieną savavališką baitą į tris baitus 7BIT . Tai neveiksminga, tačiau ji veikia (ir atkreipkite dėmesį, kad komentaras apie nesugebėjimą siųsti failų pavadinimus ir dvejetainius duomenis yra neteisingas, paprasčiausiai nusiųskite jį kaip kitą raktą / vertės porą).

border=0

Problema, susijusi su multipart/form-data yra tai, kad ribinis atskyriklis neturėtų būti rinkmenų duomenyse (žr. RFC2388 ; jame yra gana nesėkmingas pasiteisinimas, kad neturėtų tinkamo bendro MIME tipo, kad būtų išvengta šios problemos).

Taigi, iš pirmo žvilgsnio, multipart/form-data neturi jokios reikšmės jokiam failų atsisiuntimui, dvejetainiu formatu ar kitu būdu. Jei netinkamai pasirinkote sieną, tada galiausiai turėsite problemą, nesvarbu, ar siunčiate paprastą tekstą, ar neapdorotą dvejetainį failą - serveris ras ribą neteisingoje vietoje, o failas bus sutrumpintas arba POST nepavyks.

Raktas turi pasirinkti kodavimą ir ribą, kad pasirinktas ribinis simbolis nebūtų rodomas koduotoje išvestyje. Vienas paprastas sprendimas yra naudoti base64 (nenaudokite žaliavinių dvejetainių). Base64, 3 savavališki baitai yra koduojami į keturis 7 bitų simbolius, kur išvesties simbolių rinkinys yra [A-Za-z0-9+/=] (pavyzdžiui, raidiniai ir skaitmeniniai arba „+“, „/“, „=“). = yra ypatingas atvejis ir gali būti rodomas tik koduotos produkcijos pabaigoje, kaip vienas = arba dvigubas == . Dabar pasirinkite sieną kaip 7 bitų ASCII eilutę, kuri negali būti rodoma base64 išvestyje. Daugelis parinkčių, kurias matote tinkle, neperduoda šio testo - pvz., MDN dokumentų formos, pvz., „Blob“ kaip siena, kai siunčiami dvejetainiai kodo duomenys nėra geri. Tačiau kažkas panašaus į "! Blob!" niekada neatsiranda base64 išvestyje.

97
18 апр. atsakymas pateikiamas EML 18 Bal 2014-04-18 14:08 '14, 14:08 2014-04-18 14:08

Nemanau, kad „HTTP“ apsiriboja POST daugiaparte arba x-www-form-urlencoded. Turinio tipo antraštės antraštė yra tiesi HTTP POST metodo atžvilgiu (galite užpildyti jums tinkamą MIME tipą). Tai taip pat taikoma tipinėms HTML žiniatinklio programoms (pvz., „Json“ naudingoji apkrova tapo labai populiari perduodant naudingąją apkrovą „ajax“ užklausoms).

Kalbant apie „Restful API“ per HTTP, populiariausi turinio tipai, kuriuos atėjau, yra „application / xml“ ir „application / json“.

programos / xml:

  • Duomenų dydis: XML yra labai blaivus, bet dažniausiai tai nėra problema naudojant kompresiją ir manoma, kad rašymo prieigos atvejis (pvz., per POST arba PUT) yra daug rečiau nei skaitymo prieiga (daugeliu atvejų jis yra <3% viso srauto) . Retai kur turėjau optimizuoti rašymo rezultatus
  • ne ascii simbolių buvimas: galite naudoti utf-8 kaip kodavimą XML
  • dvejetainių duomenų buvimas: jums reikės naudoti base64 kodavimą
  • failo vardo duomenys: galite įterpti šį vidinį lauką į XML

programos / „Json“

  • duomenų dydis: mažesnis nei XML, vis dar tekstas, bet galite suspausti
  • ne ascii chars: json yra utf-8
  • dvejetainiai duomenys: base64 (taip pat žr. json-binary-question )
  • failo pavadinimas: įdėkite kaip savo lauko sekciją json

dvejetainiai duomenys kaip nuosavieji ištekliai

Bandau pateikti dvejetainius duomenis kaip savo išteklius / išteklius. Jis priduria dar vieną iššūkį, bet geriau atskiria medžiagą. Pavyzdiniai vaizdai:

 POST /images Content-type: multipart/mixed; boundary="xxxx" ... multipart data 201 Created Location: http://imageserver.org/../foo.jpg  POST /images Content-type: multipart/mixed; boundary="xxxx" ... multipart data 201 Created Location: http://imageserver.org/../foo.jpg 

Vėlesniuose šaltiniuose galite tiesiog įterpti dvejetainį šaltinį kaip nuorodą:

 <main-resource ... <link href="http://imageserver.org/../foo.jpg"/> </main-resource><main-resource ... <link href="http://imageserver.org/../foo.jpg"/> </main-resource> 
80
24 окт. manuel aldana atsakymas 24 a. 2010-10-24 19:46 '10, 19:46, 2010-10-24 19:46

Sutinku su tuo, ką pasakė Manuelis. Iš tiesų, jo komentarai susiję su šiuo URL ...

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4

... kurioje rašoma:

Turinio tipas "application / x-www-form-urlencoded" nėra veiksmingas siunčiant didelius kiekius dvejetainių duomenų arba teksto, kuriame yra ne ASCII simbolių. Turinio tipas "multipart / form-data" turėtų būti naudojamas pateikiant formas, kuriose yra ne ASCII duomenų ir dvejetainių duomenų.

Tačiau man tai bus siejama su įrankių / rėmelių palaikymu.

  • Kokias priemones ir sistemą naudojate tikitės, kad API naudotojai sukurtų savo programas?
  • Ar jie turi sistemas ar komponentus, kuriuos jie gali naudoti, kad prisidėtų prie vieno kito metodo?

Jei aiškiai suprasite savo vartotojus ir kaip jie naudos jūsų API, tai padės jums nuspręsti. Jei įkeliate failus į savo API naudotojus, jie išnyks ir jūs daug laiko praleidžiate juos palaikydami.

Antrinis dalykas - tai pagalbinė priemonė, skirta jūsų API rašymui, ir tai, kaip paprasta yra vieną pakrovimo mechanizmą perkelti į kitą.

24
27 окт. Martin Peck atsakymas, spalio 27 d 2010-10-27 15:08 '10, 15:08, 2010-10-27 15:08

Trumpas užuomina apie HTML5 drobės vaizdo duomenų įkėlimą:

Dirbu su spaustuvės projektu ir susidūriau su problemomis dėl nuotraukų įkėlimo į serverį, kuris atsirado iš HTML5 canvas . Bent valandą kovojau, ir aš to nepadariau tinkamai išsaugoti savo serveryje.

Kai tik aš nustatysiu savo „jQuery ajax“ skambučio „ contentType versiją „ application/x-www-form-urlencoded viskas vyko teisingai, o base64 koduoti duomenys buvo teisingai interpretuoti ir sėkmingai išsaugoti kaip vaizdas.


Gal tai padeda kam nors!

0
10 дек. atsakymas duotas habaMedia 10 gr. 2015-12-10 18:07 '15, 18:07 2015-12-10 18:07

Kiti klausimai apie žymes arba Užduoti klausimą