HTTP:ssä on kaksi tapaa POST-tietojen lähettämiseen: application/x-www-form-urlencoded
ja multipart/form-data
. Ymmärtääkseni useimmat selaimet pystyvät lataamaan tiedostoja vain, jos käytetään multipart/form-data
-tapaa. Onko olemassa lisäohjeita siitä, milloin jotakin näistä koodaustyypeistä tulisi käyttää API-yhteydessä (ilman selainta)? Tämä voisi perustua esimerkiksi seuraaviin seikkoihin:
Periaatteessa en ole toistaiseksi löytänyt verkosta virallisia ohjeita eri sisältötyyppien käytöstä.
TL;DR
Yhteenveto; jos sinulla on siirrettävänä binääristä (ei-alfanumeerista) dataa (tai huomattavan kokoista hyötykuormaa), käytä multipart/form-data
. Muussa tapauksessa käytä application/x-www-form-urlencoded
.
Mainitsemasi MIME-tyypit ovat HTTP POST -pyyntöjen kaksi Content-Type
-otsikkoa, joita käyttäjäagenttien (selaimien) on tuettava. Molempien näiden pyyntöjen tarkoituksena on lähettää palvelimelle luettelo nimi/arvopareista. Lähetettävän datan tyypistä ja määrästä riippuen toinen menetelmistä on tehokkaampi kuin toinen. Ymmärtääksesi miksi, sinun on tarkasteltava, mitä kumpikin menetelmä tekee.
Kun kyseessä on application/x-www-form-urlencoded
, palvelimelle lähetettävän HTTP-viestin runko on pohjimmiltaan yksi jättimäinen kyselymerkkijono - nimi/arvoparit erotetaan toisistaan jae-merkillä (&
) ja nimet erotetaan arvoista yhtäsuuruusmerkillä (=
). Esimerkki tästä olisi:
MyVariableOne=ValueOne&MyVariableTwo=ValueTwo
(OmaMuuttujaYkkönen=ArvoYkkönen&OmaMuuttujaKakkonen=ArvoKakkonen)
[määrittelyn] (http://www.w3.org/TR/html401/interact/forms.html) mukaan:
[Varattu ja] muut kuin aakkosnumeeriset merkit korvataan `%HH':llä, prosenttimerkillä ja kahdella heksadesimaaliluvulla, jotka edustavat merkin ASCII-koodia.
Tämä tarkoittaa sitä, että jokaista arvossamme esiintyvää ei-alfanumeerista tavua kohti tarvitaan kolme tavua sen esittämiseen. Suurissa binääritiedostoissa hyötykuorman kolminkertaistaminen on erittäin tehotonta.
Tässä kohtaa "multipart/form-data" tulee kuvaan mukaan. Tässä nimi-arvoparien lähetysmenetelmässä jokainen pari esitetään MIME-viestin "osana" (kuten muissa vastauksissa on kuvattu). Osat erotetaan toisistaan tietyllä merkkijonorajalla (joka on valittu erityisesti siten, että tämä merkkijono ei esiinny missään "value"-hyötykuormassa). Kullakin osalla on omat MIME-otsikkonsa, kuten Content-Type
ja erityisesti Content-Disposition
, jotka voivat antaa kullekin osalle sen "nimen." Kunkin nimi/arvo -parin arvo-osa on MIME-viestin kunkin osan hyötykuorma. MIME-määrittely antaa meille enemmän vaihtoehtoja arvojen hyötykuorman esittämiseen - voimme valita tehokkaamman binääridatan koodauksen kaistanleveyden säästämiseksi (esim. base 64 tai jopa raw binary).
Miksi ei käytettäisi aina multipart/form-data
? Lyhyiden aakkosnumeeristen arvojen (kuten useimmat web-lomakkeet) kohdalla kaikkien MIME-otsakkeiden lisäämisestä aiheutuva yleiskustannus on huomattavasti suurempi kuin tehokkaamman binäärikoodauksen tuomat säästöt.
En usko, että HTTP on rajoitettu POSTiin moniosaisessa tai x-www-form-urlenkoodatussa muodossa. Content-Type Header on ortogonaalinen HTTP POST -menetelmälle (voit täyttää MIME-tyypin, joka sopii sinulle). Tämä pätee myös tyypillisiin HTML-edustukseen perustuviin verkkosovelluksiin (esim. json-palkkakuormasta tuli hyvin suosittu ajax-pyyntöjen hyötykuorman välittämiseen).
Restful API:n osalta HTTP:n kautta suosituimmat sisältötyypit, joihin olen törmännyt, ovat application/xml ja application/json.
Yritän esittää binääridatan omana assetina/resurssina. Se lisää toisen kutsun, mutta purkaa asiat paremmin. Esimerkkikuvat:
POST /images
Content-type: multipart/mixed; boundary="xxxx"
... multipart data
201 Created
Sijainti: http://imageserver.org/../foo.jpg
Myöhemmissä resursseissa voit yksinkertaisesti rivittää binääriresurssin linkkinä:
Olen samaa mieltä monista Manuelin sanoista. Itse asiassa hänen kommenttinsa viittaavat tähän url-osoitteeseen....
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
... jossa todetaan:
Sisältötyyppi "application/x-www-form-urlencoded" is tehoton lähetettäessä suuria binääridatan tai tekstin määrän lähettämiseen. joka sisältää muita kuin ASCII-merkkejä. sisältötyyppi "multipart/form-data" tulisi käyttää lomakkeiden lähettämiseen. jotka sisältävät tiedostoja, ei-ASCII-tietoja, ja binääritietoja.
Minulle se riippuu kuitenkin työkalun/kehyksen tuesta.
Jos sinulla on selkeä käsitys käyttäjistäsi ja siitä, miten he käyttävät sovellusrajapintaasi, se auttaa päätöksenteossa. Jos teet tiedostojen lataamisen vaikeaksi API-käyttäjillesi, he siirtyvät pois, ja sinä käytät paljon aikaa heidän tukemiseensa.
Toissijaista tässä olisi se, millainen tuki sinulla on API:n kirjoittamiseen ja kuinka helppoa sinun on sovittaa yksi latausmekanismi toiseen.