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

HTTP sistemoje yra du duomenų siuntimo POST būdai: application/x-www-form-urlencoded ir multipart/form-data. Suprantu, kad dauguma naršyklių gali įkelti failus tik tada, kai naudojama multipart/form-data. Ar yra kokių nors papildomų rekomendacijų, kada naudoti vieną iš kodavimo tipų API kontekste (be naršyklės)? Tai gali būti pagrįsta, pvz:

  • duomenų dydžiu
  • ne ASCII simbolių buvimu
  • (nekoduotų) dvejetainių duomenų buvimu
  • poreikiu perduoti papildomus duomenis (pvz., failo pavadinimą)

Internete iš esmės neradau jokių oficialių gairių dėl skirtingų turinio tipų naudojimo.

Sprendimas

TL;DR

Apibendrinimas; jei norite perduoti dvejetainius (ne alfanumerinius) duomenis (arba didelės apimties krovinį), naudokite multipart/form-data. Priešingu atveju naudokite application/x-www-form-urlencoded.


MIME tipai, kuriuos minite, yra dvi HTTP POST užklausų Content-Type antraštės, kurias turi palaikyti naudotojo agentai (naršyklės). Abiejų šių tipų užklausų tikslas - siųsti į serverį vardų ir verčių porų sąrašą. Priklausomai nuo siunčiamų duomenų tipo ir kiekio, vienas iš metodų bus efektyvesnis už kitą. Kad suprastumėte, kodėl, turite pažvelgti, ką kiekvienas iš jų daro po dangteliu.

Naudojant application/x-www-form-urlencoded, HTTP pranešimo, siunčiamo į serverį, kūnas iš esmės yra viena didžiulė užklausos eilutė - vardų ir verčių poros atskiriamos ampersandu (&), o vardai nuo verčių atskiriami lygybės simboliu (=). Pavyzdys būtų toks: 

MyVariableOne=VertėOne&MyVariableTwo=VertėTwo

Pagal [specifikaciją] (http://www.w3.org/TR/html401/interact/forms.html):

[Rezervuota ir] nealfanumeriniai simboliai pakeičiami `%HH', procento ženklu ir dviem šešioliktainiais skaitmenimis, reiškiančiais simbolio ASCII kodą

Tai reiškia, kad kiekvienam ne raidžių ir skaičių baitui, esančiam vienoje iš mūsų verčių, atvaizduoti prireiks trijų baitų. Dideliems dvejetainiams failams trigubinti naudingąjį krūvį bus labai neefektyvu.

Štai kur atsiranda multipart/form-data. Naudojant šį vardų ir verčių porų perdavimo būdą, kiekviena pora pateikiama kaip "dalis" MIME pranešime (kaip aprašyta kituose atsakymuose). Dalys atskiriamos tam tikra ribine eilute (specialiai parinkta taip, kad šios ribinės eilutės nebūtų nė viename "vertės" krovinyje). Kiekviena dalis turi savo MIME antraščių rinkinį, pavyzdžiui, Content-Type, ir ypač Content-Disposition, kuris gali suteikti kiekvienai daliai "vardą"; Kiekvienos vardo ir vertės poros vertės dalis yra kiekvienos MIME pranešimo dalies naudingoji apkrova. MIME specifikacija suteikia mums daugiau galimybių atvaizduoti vertės naudingąją apkrovą - galime pasirinkti efektyvesnę dvejetainių duomenų koduotę, kad sutaupytume duomenų srauto pralaidumą (pvz., bazinę 64 arba net neapdorotą dvejetainę).

Kodėl ne visą laiką naudoti multipart/form-data? Jei tai trumpos raidinės-skaitmeninės vertės (pvz., dauguma žiniatinklio formų), pridedant visas MIME antraštes patiriamos pridėtinės išlaidos bus daug didesnės už sutaupytas lėšas dėl efektyvesnio dvejetainio kodavimo.

Komentarai (16)

Nemanau, kad HTTP apsiriboja tik POST daugiašale arba x-www-form-urlencoded. Antraštė [Content-Type Header][1] yra ortogonali HTTP POST metodui (galite užpildyti jums tinkamą MIME tipą). Taip yra ir tipinėse HTML atvaizdavimu pagrįstose žiniatinklio programose (pvz. json payload tapo labai populiarus perduodant ajax užklausų payload).

Kalbant apie Restful API per HTTP, populiariausi turinio tipai, su kuriais teko susidurti, yra application/xml ir application/json.

application/xml:

  • data-size: XML labai daug žodžių, bet paprastai tai nėra problema, jei naudojamas suspaudimas ir galvojama, kad rašymo prieigos atvejis (pvz., per POST arba PUT) yra daug retesnis nei skaitymo prieigos atvejis (daugeliu atvejų jis sudaro
Komentarai (3)

Sutinku su daugeliu Manuelio žodžių. Tiesą sakant, jo komentarai susiję su šiuo url adresu...

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

... kuriame teigiama:

Turinio tipas "application/x-www-form-urlencoded" yra neefektyvus siunčiant didelius dvejetainių duomenų ar teksto kiekius kuriame yra ne ASCII simbolių. turinio tipas "multipart/form-data" turėtų būti naudojamas formoms siųsti kuriose yra failų, ne ASCII duomenų, ir dvejetainiai duomenys.

Tačiau man tai priklausytų nuo įrankių ir (arba) pagrindų palaikymo.

  • Kokias priemones ir karkasus naudojate tikitės, kad jūsų API naudotojai kurs programėles?
  • Ar jie turi karkasus ar komponentus, kuriuos jie gali naudoti kurie teikia pirmenybę vienam metodui, o ne kitam. kitam?

Jei aiškiai įsivaizduosite savo naudotojus ir tai, kaip jie naudosis jūsų API, tai padės jums apsispręsti. Jei API naudotojams bus sunku įkelti failus, jie pasitrauks, o jūs sugaišite daug laiko jiems palaikyti.

Antraeilis dalykas būtų tai, kokią paramą įrankiais jūs turite rašydami API ir kaip lengva jums pritaikyti vieną įkėlimo mechanizmą, o ne kitą.

Komentarai (2)