application/x-www-form-urlencoded tai multipart/form-data?

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:

  • datan koko
  • muiden kuin ASCII-merkkien olemassaolo
  • (koodaamattoman) binääridatan olemassaolo.
  • tarve siirtää lisätietoja (kuten tiedostonimi).

Periaatteessa en ole toistaiseksi löytänyt verkosta virallisia ohjeita eri sisältötyyppien käytöstä.

Ratkaisu

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.

Kommentit (16)

En usko, että HTTP on rajoitettu POSTiin moniosaisessa tai x-www-form-urlenkoodatussa muodossa. [Content-Type Header][1] 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.

application/xml:

  • data-size: XML hyvin sanallinen, mutta yleensä ei ole ongelma, kun käytetään pakkausta ja ajatellaan, että kirjoitusoikeudet (esim. POSTin tai PUTin kautta) ovat paljon harvinaisempia kuin lukuoikeudet (monissa tapauksissa ne ovat
Kommentit (3)

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.

  • Mitä työkaluja ja kehyksiä te API-käyttäjiesi rakentavan sovelluksiaan?
  • Onko heillä kehyksiä tai komponentteja, joita he voivat käyttää jotka suosivat yhtä menetelmää toista menetelmää?

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.

Kommentit (2)