In HTTP zijn er twee manieren om gegevens te POST-en: application/x-www-form-urlencoded
en multipart/form-data
. Ik heb begrepen dat de meeste browsers alleen bestanden kunnen uploaden als multipart/form-data
wordt gebruikt. Zijn er aanvullende richtlijnen voor het gebruik van een van de coderingstypes in een API context (zonder browser)? Dit zou bijvoorbeeld gebaseerd kunnen zijn op:
Tot nu toe heb ik op het web geen formele richtsnoeren gevonden voor het gebruik van de verschillende inhoudstypen.
TL;DR
Samenvatting; als je binaire (niet-alfanumerieke) data (of een payload van aanzienlijke grootte) wilt verzenden, gebruik dan multipart/form-data
. Anders, gebruik application/x-www-form-urlencoded
.
De MIME types die je noemt zijn de twee Content-Type
headers voor HTTP POST requests die user-agents (browsers) moeten ondersteunen. Het doel van beide soorten verzoeken is om een lijst van naam/waarde paren naar de server te sturen. Afhankelijk van het type en de hoeveelheid gegevens die worden verzonden, zal een van de methoden efficiënter zijn dan de andere. Om te begrijpen waarom, moet je kijken naar wat beide onder de dekmantel doen.
Voor application/x-www-form-urlencoded
, is de body van het HTTP bericht dat naar de server wordt gestuurd in wezen één grote query string -- naam/waarde paren worden gescheiden door de ampersand (&
), en namen worden van waarden gescheiden door het gelijk-teken (=
). Een voorbeeld hiervan zou zijn:
MijnVariabeleEén=WaardeEén&MijnVariabeleTwee=WaardeTwee
.
Volgens de [specificatie] (http://www.w3.org/TR/html401/interact/forms.html):
[Gereserveerde en] niet-alfanumerieke tekens worden vervangen door `%HH', een procentteken en twee hexadecimale cijfers die de ASCII-code van het teken weergeven
Dat betekent dat voor elke niet-alfanumerieke byte in een van onze waarden, er drie bytes nodig zijn om die weer te geven. Voor grote binaire bestanden zal het verdrievoudigen van de payload zeer inefficiënt zijn.
Dat is waar multipart/form-data
om de hoek komt kijken. Met deze methode voor het verzenden van naam/waarde paren, wordt elk paar weergegeven als een "part" in een MIME bericht (zoals beschreven in andere antwoorden). De delen worden gescheiden door een bepaalde stringgrens (speciaal zo gekozen dat deze grensstring niet voorkomt in een van de "value" payloads). Elk deel heeft zijn eigen set MIME headers zoals Content-Type
, en in het bijzonder Content-Disposition
, die elk deel zijn "name." Het waarde deel van elk naam/waarde paar is de payload van elk deel van het MIME bericht. De MIME spec geeft ons meer opties bij het weergeven van de waarde payload -- we kunnen een efficiëntere codering van binaire gegevens kiezen om bandbreedte te besparen (b.v. base 64 of zelfs raw binary).
Waarom niet altijd multipart/form-data
gebruiken? Voor korte alfanumerieke waarden (zoals de meeste webformulieren) zal de overhead van het toevoegen van alle MIME headers veel groter zijn dan de besparing van een efficiëntere binaire codering.
Ik denk niet'dat HTTP beperkt is tot POST in multipart of x-www-form-urlencoded. De Content-Type Header is orthogonaal aan de HTTP POST methode (je kunt MIME type invullen dat bij je past). Dit is ook het geval voor typische HTML representatie gebaseerde webapps (bv. json payload werd zeer populair voor het verzenden van payload voor ajax verzoeken).
Wat betreft Restful API over HTTP zijn de meest populaire content-types waar ik mee in aanraking ben gekomen application/xml en application/json.
Ik zou proberen om binaire data als eigen asset/resource weer te geven. Het voegt een andere oproep toe, maar ontkoppelt dingen beter. Voorbeeld afbeeldingen:
POST /images
Content-type: multipart/mixed; boundary="xxxx"
... multipart gegevens
201 Aangemaakt
Locatie: http://imageserver.org/../foo.jpg
In latere bronnen zou je de binaire bron gewoon als link kunnen inlinen:
Ik ben het eens met veel van wat Manuel heeft gezegd. In feite, zijn opmerkingen verwijzen naar deze url...
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
... waarin staat:
Het inhoudstype "application/x-www-form-urlencoded" is inefficiënt voor het verzenden van grote hoeveelheden binaire data of tekst die niet-ASCII tekens bevat. De content type "multipart/form-data" moet worden gebruikt voor het verzenden van formulieren die bestanden, niet-ASCII gegevens bevatten, en binaire data.
Voor mij zou het echter neerkomen op tool/framework ondersteuning.
Als je een duidelijk beeld krijgt van je gebruikers, en hoe zij'gebruik zullen maken van je API, dan zal dat je helpen beslissen. Als u het uploaden van bestanden moeilijk maakt voor uw API-gebruikers dan zullen zij'weggaan, of u'zult veel tijd besteden aan het ondersteunen van hen.
Secundair aan dit zou zijn de tool ondersteuning JIJ hebt voor het schrijven van uw API en hoe gemakkelijk het is voor uw om een upload mechanisme tegemoet te komen over de andere.