A HTTP-ben az adatok POST-olásának két módja van: application/x-www-form-urlencoded
és multipart/form-data
. Úgy tudom, hogy a legtöbb böngésző csak a multipart/form-data
használata esetén képes fájlokat feltölteni. Van további útmutatás arra vonatkozóan, hogy mikor kell valamelyik kódolási típust használni API-kontextusban (böngésző nélkül)? Ez például a következőkön alapulhat:
A különböző tartalomtípusok használatára vonatkozóan eddig alapvetően nem találtam hivatalos útmutatást a weben.
TL;DR
Összefoglalva; ha bináris (nem alfanumerikus) adatokat (vagy jelentős méretű hasznos terhet) kell továbbítanod, használd a "multipart/form-data" opciót. Ellenkező esetben használd az application/x-www-form-urlencoded
opciót.
Az Ön által említett MIME típusok a HTTP POST kérések két Content-Type
fejlécét jelentik, amelyeket a felhasználói ügynököknek (böngészőknek) támogatniuk kell. Mindkét típusú kérés célja, hogy név/érték párok listáját küldje el a kiszolgálónak. A továbbítandó adatok típusától és mennyiségétől függően az egyik módszer hatékonyabb lesz, mint a másik. Ahhoz, hogy megértsük, miért, meg kell néznünk, mit csinálnak a fedő alatt.
Az application/x-www-form-urlencoded
esetében a kiszolgálónak küldött HTTP-üzenet teste lényegében egy hatalmas lekérdezési karakterlánc - a név/érték párokat az írásjel (&
) választja el, a neveket pedig az egyenlőségjel (=
) választja el az értékektől. Egy példa erre:
MyVariableOne=ValueOne&MyVariableTwo=ValueTwo
A specifikáció szerint:
[Fenntartott és] a nem alfanumerikus karakterek helyébe a karakter ASCII kódját jelző `%HH', egy százalékjel és két hexadecimális számjegy lép.
Ez azt jelenti, hogy minden egyes nem-alfanumerikus bájtra, amely az egyik értékünkben létezik, három bájtot kell használni a megjelenítéséhez. Nagy bináris fájlok esetén a hasznos adatmennyiség megháromszorozása rendkívül gazdaságtalan.
Itt jön a képbe a "multipart/form-data". A név/érték párok továbbításának ezen módszerével minden egyes pár egy MIME-üzenet "részeként" jelenik meg (ahogyan azt más válaszok leírják). A részeket egy adott karakterlánc határolja el egymástól (amelyet kifejezetten úgy választanak ki, hogy ez a határoló karakterlánc ne forduljon elő az "érték" hasznos töltetének egyikében sem). Minden egyes résznek saját MIME fejlécei vannak, mint például a Content-Type
és különösen a Content-Disposition
, amelyek minden résznek megadhatják a "nevét". Az egyes név/érték párok értékdarabja a MIME-üzenet egyes részeinek hasznos terhe. A MIME specifikáció több lehetőséget ad az érték hasznos terhének ábrázolásakor -- a sávszélesség megtakarítása érdekében választhatjuk a bináris adatok hatékonyabb kódolását (pl. 64-es bázis vagy akár nyers bináris).
Miért ne használhatnánk mindig a multipart/form-data
t? Rövid alfanumerikus értékek esetén (mint a legtöbb webes űrlap) az összes MIME fejléc hozzáadásának többletköltsége jelentősen meghaladja a hatékonyabb bináris kódolásból származó megtakarításokat.
Nem hiszem, hogy a HTTP a POST-ra korlátozódik multipart vagy x-www-form-urlencoded esetén. A Content-Type Header ortogonális a HTTP POST módszerhez (kitöltheti a MIME-típust, amelyik megfelel). Ez a tipikus HTML-reprezentáción alapuló webalkalmazások esetében is így van (pl. a json payload nagyon népszerűvé vált az ajax-kérések payloadjának továbbítására).
A HTTP-n keresztüli Restful API-t illetően a legnépszerűbb tartalomtípusok, amelyekkel kapcsolatba kerültem, az application/xml és az application/json.
Megpróbálnám a bináris adatokat saját eszközként/erőforrásként ábrázolni. Ez egy újabb hívást ad hozzá, de jobban szétválasztja a dolgokat. Példa képek:
POST /images
Content-type: multipart/mixed; boundary="xxxx"
... multipart adatok
201 Created
Hely: http://imageserver.org/../foo.jpg
A későbbi erőforrásokban egyszerűen beillesztheted a bináris erőforrást linkként:
Sok mindennel egyetértek, amit Manuel mondott. Valójában a megjegyzései erre az url-re utalnak...
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
... amely kimondja:
A tartalom típusa "application/x-www-form-urlencoded" a következő nem hatékony a nagyméretű bináris adat- vagy szövegmennyiségek továbbítására nem ASCII karaktereket tartalmazó szöveg küldésére. A tartalomtípus "multipart/form-data" formanyomtatványok küldéséhez kell használni amelyek fájlokat, nem ASCII adatokat tartalmaznak, és bináris adatokat tartalmaznak.
Számomra azonban ez az eszköz/keretrendszer támogatásán múlik.
Ha világos képet kap a felhasználókról, és arról, hogyan fogják használni az API-t, akkor ez segít a döntésben. Ha megnehezíti a fájlok feltöltését az API-felhasználók számára, akkor el fognak távolodni, és sok időt kell fordítania a támogatásukra.
Ehhez képest másodlagos lenne, hogy milyen eszköztámogatással rendelkezik az API megírásához, és hogy mennyire könnyű az Ön számára az egyik feltöltési mechanizmust a másikkal szemben alkalmaznia.