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

I HTTP er det to måter å POST-data på: application/x-www-form-urlencoded og multipart/form-data. Jeg forstår at de fleste nettlesere bare kan laste opp filer hvis multipart/form-data brukes. Finnes det noen ytterligere veiledning for når en av kodingstypene skal brukes i API-sammenheng (uten at nettleseren er involvert)? Dette kan f.eks. være basert på:

  • datastørrelse
  • forekomst av ikke-ASCII-tegn
  • forekomst av (ukodede) binære data
  • behovet for å overføre tilleggsdata (f.eks. filnavn)

Jeg har i utgangspunktet ikke funnet noen formell veiledning på nettet om bruken av de ulike innholdstypene så langt.

Løsning

TL;DR

Sammendrag; hvis du har binære (ikke-alfanumeriske) data (eller en betydelig nyttelast) som skal overføres, bruk multipart/form-data. Ellers, bruk application/x-www-form-urlencoded.


MIME-typene du nevner er de to Content-Type-headerne for HTTP POST-forespørsler som brukeragenter (nettlesere) må støtte. Formålet med begge disse typene forespørsler er å sende en liste med navn/verdi-par til serveren. Avhengig av typen og mengden data som overføres, vil en av metodene være mer effektiv enn den andre. For å forstå hvorfor, må du se på hva hver av dem gjør under dekslene.

For application/x-www-form-urlencoded er brødteksten i HTTP-meldingen som sendes til serveren i hovedsak en gigantisk spørringsstreng - navn/verdi-par er atskilt med ampersand (&), og navn er atskilt fra verdier med likhetstegnet (=). Et eksempel på dette kan være: 

MyVariableOne=ValueOne&MyVariableTwo=ValueTwo`.

I henhold til spesifikasjonen:

[Reserverte og] ikke-alfanumeriske tegn erstattes av `%HH', et prosenttegn og to heksadesimale sifre som representerer tegnets ASCII-kode

Det betyr at for hver ikke-alfanumerisk byte som finnes i en av verdiene våre, vil det ta tre byte å representere den. For store binære filer vil tredobling av nyttelasten være svært ineffektivt.

Det er her multipart/form-data kommer inn i bildet. Med denne metoden for overføring av navn/verdi-par representeres hvert par som en "del" i en MIME-melding (som beskrevet i andre svar). Delene er atskilt med en bestemt strenggrense (valgt spesielt slik at denne grensestrengen ikke forekommer i noen av nyttelastene). Hver del har sitt eget sett med MIME-overskrifter som Content-Type, og spesielt Content-Disposition, som kan gi hver del sitt navn. Verdidelen av hvert navn/verdi-par er nyttelasten til hver del av MIME-meldingen. MIME-spesifikasjonen gir oss flere alternativer når vi representerer nyttelasten - vi kan velge en mer effektiv koding av binære data for å spare båndbredde (f.eks. base 64 eller til og med rå binær).

Hvorfor ikke bruke multipart/form-data hele tiden? For korte alfanumeriske verdier (som de fleste nettskjemaer) vil overheadkostnadene ved å legge til alle MIME-headerne i betydelig grad oppveie eventuelle besparelser ved mer effektiv binær koding.

Kommentarer (16)

Jeg tror ikke HTTP er begrenset til POST i multipart eller x-www-form-urlencoded. Content-Type Header][1] er ortogonal til HTTP POST-metoden (du kan fylle MIME-typen som passer deg). Dette er også tilfelle for typiske HTML-representasjonsbaserte webapplikasjoner (f.eks. ble json-nyttelast veldig populært for overføring av nyttelast for ajax-forespørsler).

Når det gjelder Restful API over HTTP, er de mest populære innholdstypene jeg kom i kontakt med application/xml og application/json.

application/xml:

  • data-size: XML veldig ordrik, men vanligvis ikke et problem når du bruker komprimering og tenker at skrivetilgangssaken (f.eks. Gjennom POST eller PUT) er mye mer sjelden som lesetilgang (i mange tilfeller er det
Kommentarer (3)

Jeg er enig i mye av det Manuel har sagt. Faktisk henviser kommentarene hans til denne nettadressen ...

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4

... der det står

Innholdstypen "application/x-www-form-urlencoded" er ineffektiv for sending av store store mengder binære data eller tekst som inneholder ikke-ASCII-tegn. Den innholdstypen "multipart/form-data" bør brukes til innsending av skjemaer som inneholder filer, ikke-ASCII-data, og binære data.

For meg ville det imidlertid dreie seg om støtte for verktøy/rammeverk.

  • Hvilke verktøy og rammeverk forventer du forventer du at API-brukerne dine skal bygge appene sine med?
  • Har de rammeverk eller komponenter de kan bruke som favoriserer den ene metoden fremfor den den andre?

Hvis du får en klar idé om brukerne dine, og hvordan de vil bruke API-et ditt, vil det hjelpe deg med å bestemme deg. Hvis du gjør opplastingen av filer vanskelig for API-brukerne dine, vil de flytte bort, eller du vil bruke mye tid på å støtte dem.

Sekundært til dette vil være verktøystøtten DU har for å skrive API-et ditt og hvor enkelt det er for deg å imøtekomme den ene opplastingsmekanismen fremfor den andre.

Kommentarer (2)