V protokolu HTTP obstajata dva načina pošiljanja podatkov POST: application/x-www-form-urlencoded
in multipart/form-data
. Razumem, da lahko večina brskalnikov naloži datoteke samo, če se uporabi multipart/form-data
. Ali obstajajo kakšna dodatna navodila, kdaj uporabiti eno od vrst kodiranja v kontekstu API (brez vključenega brskalnika)? To bi lahko temeljilo npr. na:
Na spletu v bistvu do zdaj nisem našel uradnih navodil glede uporabe različnih tipov vsebine.
TL;DR
Povzetek; če želite posredovati binarne (nealfanumerične) podatke (ali precej velik tovor), uporabite multipart/form-data
. V nasprotnem primeru uporabite application/x-www-form-urlencoded
.
Tipa MIME, ki ju omenjate, sta dve glavi Content-Type
za zahteve HTTP POST, ki ju morajo podpirati uporabniški agenti (brskalniki). Namen obeh vrst zahtevkov je poslati strežniku seznam parov ime/vrednost. Odvisno od vrste in količine podatkov, ki se prenašajo, bo ena od metod učinkovitejša od druge. Da bi razumeli, zakaj, si morate ogledati, kaj vsaka od teh metod počne pod pokrovom.
Pri načinu application/x-www-form-urlencoded
je telo sporočila HTTP, poslanega strežniku, v bistvu en sam velik niz poizvedb - pari ime/vrednost so ločeni z ampersandom (&
), imena pa so od vrednosti ločena s simbolom enakosti (=
). Primer tega je:
MojaPremenljivkaJeden=VrednostJeden&MojaPremenljivkaDva=VrednostDva
V skladu s specifikacijo:
[Rezervirano in] nealfanumerični znaki se nadomestijo z `%HH', znakom odstotka in dvema šestnajstmestnima številkama, ki predstavljata kodo ASCII znaka
To pomeni, da bodo za vsak nealfanumerični bajt, ki obstaja v eni od naših vrednosti, potrebni trije bajti, da ga predstavimo. Pri velikih binarnih datotekah bo potrojitev bremena zelo neučinkovita.
Zato pride na vrsto multipart/form-data
. Pri tej metodi prenosa parov ime/vrednost je vsak par predstavljen kot "del" v sporočilu MIME (kot je opisano v drugih odgovorih). Deli so ločeni z določenim mejnim nizom (izbranim posebej tako, da se ta mejni niz ne pojavi v nobenem od "vrednostnih" bremen). Vsak del ima svoj nabor glave MIME, kot sta Content-Type
in zlasti Content-Disposition
, ki lahko vsakemu delu določita "ime." Del vrednosti vsakega para ime/vrednost je koristni tovor vsakega dela sporočila MIME. Specifikacija MIME nam daje več možnosti pri predstavitvi vrednostnega tovora - izberemo lahko učinkovitejše kodiranje binarnih podatkov, da prihranimo pasovno širino (npr. base 64 ali celo raw binary).
Zakaj ne bi ves čas uporabljali multipart/form-data
? Pri kratkih alfanumeričnih vrednostih (kot je večina spletnih obrazcev) bodo stroški dodajanja vseh glave MIME bistveno večji od prihrankov zaradi učinkovitejšega binarnega kodiranja.
Mislim, da HTTP ni omejen na POST v večdelnem ali x-www-form-urlencoded. Naslovnica Content-Type je ortogonalna glede na metodo HTTP POST (lahko izpolnite tip MIME, ki vam ustreza). To velja tudi za tipične spletne aplikacije, ki temeljijo na predstavitvi HTML (npr. payload json je postal zelo priljubljen za prenos payloada za zahteve ajax).
V zvezi z Restful API prek HTTP sta najbolj priljubljena tipa vsebine, s katerima sem se srečal, application/xml in application/json.
Binarne podatke bi poskušal predstaviti kot lastno sredstvo/izvir. To doda še en klic, vendar bolje loči stvari. Primer slik:
POST /images
Content-type: multipart/mixed; boundary="xxxx"
... večdelni podatki
201 Ustvarjeno
Lokacija: http://imageserver.org/../foo.jpg
V kasnejših virih lahko preprosto vnesete binarni vir kot povezavo:
Strinjam se z mnogimi Manuelovimi besedami. Pravzaprav se njegove pripombe nanašajo na ta url naslov...
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
... ki navaja:
Vrsta vsebine "application/x-www-form-urlencoded" je neučinkovita za pošiljanje velikih količin binarnih podatkov ali besedila ki vsebujejo znake, ki niso znaki ASCII. Na spletni strani vrsta vsebine "multipart/form-data" je treba uporabljati za pošiljanje obrazcev ki vsebujejo datoteke, podatke, ki niso v zapisu ASCII, in binarne podatke.
Vendar pa se mi zdi, da je to odvisno od podpore orodja/okvirja.
Če imate jasno predstavo o svojih uporabnikih in o tem, kako bodo uporabljali vaš API, vam bo to pomagalo pri odločitvi. Če uporabnikom API otežite nalaganje datotek, se bodo umaknili, vi pa boste porabili veliko časa za njihovo podporo.
Poleg tega bi bilo pomembno tudi, kakšno podporo imate vi za pisanje API-ja in kako enostavno je za vas prilagoditi en mehanizem za nalaganje datotek drugemu.