Ang Multipart Upload ay isang HTTP mechanism na nagpapahintulot sa pagpapadala ng maraming magkakaibang bahagi ng data sa isang request, kabilang ang mga text field at binary file. Ang bawat bahagi ay pinaghihiwalay ng isang natatanging boundary string at may sariling Content-Type header. Ayon sa MDN Web Docs, 2025, ang multipart/form-data ay ang karaniwang format para sa pag-upload ng mga file sa pamamagitan ng HTML forms at malawakang ginagamit sa web at mobile applications para sa pagpapadala ng mga larawan, dokumento, at iba pang file sa server.
Mga Pangunahing Punto
Multipart Upload ay isang paraan ng pagpapadala ng data sa pamamagitan ng HTTP protocol, kung saan ang body ng request ay binubuo ng ilang lohikal na pinaghiwalay na bahagi. Ang bawat bahagi ay maaaring maglaman ng iba't ibang uri ng data: isang text field ng form, binary file, JSON object, o larawan. Lahat ng bahagi ay nakabalot sa isang POST request, na pumapalit sa pangangailangan na magpadala ng N hiwalay na HTTP tawag. Ang Multipart Upload ay isang mahalagang bahagi ng web forms at API para sa pag-upload ng mga file.
Ang multipart format ay tinukoy sa specification na RFC 2046 bilang bahagi ng MIME standard para sa mga email message, at pagkatapos ay inangkop para sa HTTP sa RFC 1867. Ngayon sa web development halos eksklusibong ginagamit ang multipart/form-data — isa sa mga subtype ng multipart, na nilalayon para sa mga form na naglalaman ng mga file. Ang iba pang mga subtype — multipart/mixed (para sa arbitrary attachments) at multipart/byteranges (para sa partial file downloads) — ay mas bihirang ginagamit.
Ang pangunahing pagkakaiba sa pagitan ng multipart at simpleng application/x-www-form-urlencoded ay ang huli ay nag-eencode ng lahat ng data sa isang URI-compatible string at hindi sumusuporta sa binary files. Ang Multipart/form-data, sa kabaligtaran, ay nagpapadala ng bawat file sa orihinal nitong binary form nang walang encoding, na mas mahusay at hindi nawawalan ng katumpakan. Ang laki ng request sa multipart ay 5-15% lamang na mas malaki kaysa sa kabuuan ng mga laki ng file dahil sa overhead ng mga header ng bahagi at mga boundary.
Multipart Upload ay ginagamit sa lahat ng dako kung saan kinakailangan ang pag-upload ng file: mga avatar at profile picture sa social media, mga attachment sa messaging apps, mga dokumento sa CRM system, mga larawan ng produkto sa online stores. Sa mobile applications, ginagamit ang Multipart Upload para sa pagpapadala ng media content sa server — mga larawan mula sa camera ng device, voice recordings, video fragments. Ayon sa datos ng Cloudflare Research, humigit-kumulang 15% ng lahat ng POST request sa web ay gumagamit ng multipart/form-data.
Multipart Upload at Chunked Transfer ay magkaibang mekanismo. Hinahati ng Multipart ang request sa mga makabuluhang bahagi (mga field at file), habang hinahati ng Chunked Transfer ang data stream sa mga fragment para sa pagpapadala nang hindi alam ang kabuuang laki. Ang Multipart ay maaaring ipadala sa loob ng Chunked Transfer: ang server ay nagpapadala ng multipart response sa mga bahagi, nang hindi alam ang buong volume nito. Ang mga mekanismong ito ay hindi magkasalungat at lumulutas ng iba't ibang gawain sa iba't ibang antas.
Kapag ang browser ay nagpapadala ng form na may attribute na enctype="multipart/form-data", binubuo nito ang request body sa multipart format. Ang bawat field ng form ay nagiging hiwalay na block, na pinaghihiwalay mula sa iba ng boundary string. Ang boundary ay awtomatikong nabubuo at isang natatanging pagkakasunod-sunod ng mga character na garantisadong hindi matatagpuan sa loob ng data. Ang client ay nagdadagdag ng boundary na ito sa Content-Type header: multipart/form-data; boundary=----WebKitFormBoundaryX7K.
Ang bawat block ay nagsisimula sa --boundary at naglalaman ng Content-Disposition headers na may pangalan ng field (name) at, para sa mga file, orihinal na pangalan ng file (filename). Pagkatapos ng isang blangkong linya ay direktang sumusunod ang data ng field o ang nilalaman ng file sa binary form. Ang request ay nagtatapos sa string na --boundary--. Ang server ay nag-parse ng natanggap na stream: unang hinahanap ang boundary, pagkatapos ay kinukuha ang mga header ng bawat bahagi, tinutukoy ang uri ng data, at ipinapasa ang mga ito sa form handler o API controller.
Ayon sa IETF RFC 7578, ang multipart/form-data ay hindi nangangailangan ng pagtukoy ng charset para sa bawat bahagi, dahil ang mga text field ay itinuturing na UTF-8, at ang mga binary na bahagi ay naglalaman ng mga file sa orihinal na encoding. Ang laki ng isang bahagi ay hindi nililimitahan ng protocol — ang mga limitasyon ay naka-configure sa antas ng server: halimbawa, sa Nginx sa pamamagitan ng client_max_body_size, sa Spring Boot sa pamamagitan ng spring.servlet.multipart.max-file-size.
Boundary ay isang natatanging string na hindi dapat lumitaw sa ipinapadalang data. Karaniwan itong nagsisimula sa isang prefix (hal., ----WebKitFormBoundary o ----Boundary) at naglalaman ng mga random na character. Ang mga browser at HTTP client ay awtomatikong bumubuo ng boundary. Ang haba ng boundary ay hindi dapat lumampas sa 70 character ayon sa RFC 2046. Ang bawat bahagi ay pinaghihiwalay ng string na --boundary\r\n, at ang dulo ng request ay ng --boundary--\r\n.
Ang multipart request ay may mahigpit na istraktura na tinukoy ng MIME at HTTP standards. Ang request header ay nagtatakda ng Content-Type: multipart/form-data na may parameter na boundary. Ang request body ay binubuo ng isang pagkakasunod-sunod ng mga bahagi, na ang bawat isa ay naglalaman ng sarili nitong mga header at body. Ang mga header ng bahagi ay kinabibilangan ng Content-Disposition (kinakailangan) at Content-Type (opsyonal — para sa mga file). Ang pagkakaroon ng blangkong linya sa pagitan ng mga header ng bahagi at ng data nito ay kinakailangan.
| Elemento | Halimbawa | Kailangan |
|---|---|---|
| Content-Type | multipart/form-data; boundary=---Bnd123 | Oo |
| Paghihiwalay ng bahagi | ---Bnd123 | Oo (bago ang bawat bahagi) |
| Content-Disposition | form-data; name="avatar"; filename="photo.jpg" | Oo |
| Content-Type ng bahagi | image/jpeg | Para sa mga file |
| Body ng bahagi | [binary data ng larawan] | Oo |
| Pangwakas na boundary | ---Bnd123-- | Oo (dulo ng request) |
Tingnan natin ang isang tunay na halimbawa ng multipart request na nagpapadala ng text field at isang image file. Ang client ay bumubuo ng Content-Type header na may natatanging boundary. Ang request body ay sunod-sunod na naglalaman ng lahat ng field ng form. Ang server sa pagtanggap ay nag-parse ng mga bahaging ito at nagbibigay sa developer ng access sa bawat field bilang isang hiwalay na object. Ang pamamaraang ito ay nagpapahintulot sa pagproseso ng mga kumplikadong form na may mga file sa isang HTTP call.
import okhttp3.*
import java.io.File
fun uploadFile() {
val client = OkHttpClient()
val imageFile = File("/path/to/photo.jpg")
val requestBody = MultipartBody.Builder()
.setType(MediaType.parse("multipart/form-data"))
.addFormDataPart("username", "john_doe")
.addFormDataPart(
"avatar", "photo.jpg",
RequestBody.create(
MediaType.parse("image/jpeg"), imageFile
)
)
.build()
val request = Request.Builder()
.url("https://api.example.com/upload")
.post(requestBody)
.build()
client.newCall(request).execute().use { response ->
println("Na-upload: ${response.isSuccessful}")
}
}
Sa bahagi ng server, ang multipart request ay napa-parse ng framework o manu-mano. Sa Spring Boot, sapat na ang annotation na @RequestParam("avatar") MultipartFile file, at ang framework ay awtomatikong kumukuha ng file mula sa multipart request. Sa Ktor sa Kotlin, ginagamit ang receiveMultipart(), sa Express.js — ang multer middleware. Ang server ay nakakakuha ng access sa bawat field ng form at bawat na-upload na file nang independyente, ini-save ang file sa disk o cloud storage, at ibinabalik ang URL o identifier sa client.
Ang Multipart Upload ay nagbibigay ng ilang pangunahing bentahe kumpara sa mga alternatibong paraan ng pagpapadala ng data. Isang request sa halip na marami — lahat ng field ng form at file ay ipinapadala sa isang HTTP call, na nagbabawas ng karga sa network at server. Hindi na kailangang magbukas ng N koneksyon para mag-upload ng N file — lahat ay nakabalot sa isang POST. Ito ay lalong mahalaga para sa mobile applications, kung saan ang bawat HTTP connection ay nangangahulugang latency at konsumo ng baterya.
Binary transmission nang walang encoding — hindi tulad ng application/x-www-form-urlencoded, kung saan ang binary data ay n-eencode sa base64 (33% na pagtaas sa laki), ang multipart/form-data ay nagpapadala ng mga file sa orihinal na binary form. Ito ay mas mahusay sa laki at bilis. Para sa malalaking file mula 10 MB pataas, ang pagkakaiba ay nagiging kritikal: ang multipart request ay magiging 30% na mas maliit kaysa sa URL-encoded request na may parehong file.
Arbitraryong istraktura — pinapayagan ng multipart ang pagsasama-sama ng mga field ng iba't ibang uri sa anumang pagkakasunod-sunod. Ang form ay maaaring maglaman ng mga text field, maraming file, JSON data, at hidden field nang sabay-sabay. Bawat bahagi ay may sariling Content-Type, na nagpapahintulot sa paghahalo ng text at binary data. Para sa paghahambing: ang base64 encoding ay nagdaragdag ng 33% sa laki, habang ang multipart ay mga 5-15% lamang para sa mga service header.
Ayon sa pag-aaral ng HTTP Archive, 2025, ang multipart/form-data ay ginagamit sa 94% ng mga kaso ng pag-upload ng file sa web. Mga alternatibo — base64 sa JSON (4%) at direktang transmission sa pamamagitan ng WebSocket (2%). Ang JSON na may base64 ay maginhawa para sa API kung saan ang lahat ng iba pang data ay nasa JSON din, ngunit hindi mahusay para sa malalaking file. Ang WebSocket ay angkop para sa real-time, ngunit hindi sinusuportahan ng lahat ng HTTP infrastructure. Ang Multipart ay nananatiling pamantayan para sa pag-upload ng file dahil sa pagiging simple at kahusayan nito.
Sa mobile applications, ang Multipart Upload ay ginagamit para sa pagpapadala ng media content mula sa mga device ng user: mga larawan mula sa gallery, mga kuha mula sa camera, voice recordings, document file. Sa Android, ang karaniwang paraan ay OkHttp na may MultipartBody.Builder, na nagpapahintulot sa madaling pagbuo ng mga multipart request. Ang Retrofit ay sumusuporta rin sa multipart sa pamamagitan ng mga annotation na @Multipart at @Part. Tinutukoy ng developer ang uri ng data para sa bawat bahagi, at ang HTTP client ay awtomatikong bumubuo ng tamang mga header.
Sa iOS, ang parehong mga gawain ay nalulutas sa pamamagitan ng URLSession na may custom na HTTPBodyStream o sa pamamagitan ng Alamofire na may multipartFormData. Ang Alamofire ay nagbibigay ng maginhawang pamamaraan na upload(multipartFormData:) para sa pagpapadala ng mga multipart request. Sa parehong platform, mahalagang isaalang-alang ang laki ng mga file na ina-upload — para sa malalaking file (higit sa 10-20 MB), inirerekomenda ang paggamit ng background upload upang hindi magsara ang app kapag na-minimize. Sa Android, ginagamit ang DownloadManager o WorkManager para dito, sa iOS — URLSession na may background configuration.
Kapag nag-u-upload ng mga file sa mobile applications, kailangang isaalang-alang ang estado ng network. Connectivity Manager sa Android ay tumutulong na matukoy kung available ang Wi-Fi o mobile data at pumili ng pinakamainam na sandali para sa pag-upload. Para sa malalaking file tulad ng video, inirerekomenda na ipagpaliban ang pag-upload hanggang sa kumonekta sa Wi-Fi, upang hindi magamit ang mobile data ng user. Ang WorkManager sa Android ay nagpapahintulot sa pagsasaayos ng mga naturang limitasyon sa pamamagitan ng NetworkType.UNMETERED.
Bago magpadala ng file sa pamamagitan ng Multipart Upload, ang mga mobile application ay madalas na nag-compress at nagbabago ng laki ng larawan. JPEG compression na may kalidad na 85% ay nagbabawas ng laki ng file ng 3-5 beses nang walang kapansin-pansing pagkawala ng kalidad para sa pagtingin sa screen. Ang pagbabago ng laki ng larawan sa 1920px sa mas mahabang bahagi ay higit na nagbabawas ng laki. Sa Android, ginagamit ang Bitmap.compress() para dito, sa iOS — UIImageJPEGRepresentation na may compression parameter na 0.85. Ang ganitong pag-optimize ay nagpapabilis ng pag-upload at nakakatipid ng mobile data.
Ang pinakakaraniwang error sa Multipart Upload — paglampas sa limitasyon ng laki ng request sa server. Bilang default, nililimitahan ng Nginx ang laki ng request body sa 1 MB (client_max_body_size), at Tomcat sa 2 MB (maxSwallowSize). Kung hindi tataasan ng developer ang mga limitasyong ito, ibabalik ng server ang error na 413 Request Entity Too Large. Solusyon — tahasang i-configure ang maximum na laki ng pag-upload sa server at magpakita ng babala sa client kung ang file ay lumampas sa pinapayagang laki.
Pangalawang problema — hindi tamang pagproseso ng mga multipart request kapag nag-stream ng body. Ang ilang server ay sumusubok na i-load ang buong multipart request sa memory bago mag-parse, na nagdudulot ng OutOfMemoryError para sa malalaking file. Ang mga modernong server (Nginx, Spring Boot, Ktor) ay sumusuporta sa streaming parse ng multipart, kung saan ang bawat bahagi ay pinoproseso habang dumarating. Dapat tiyakin ng developer na ang server ay naka-configure para sa streaming processing ng mga multipart request.
Pangatlong kategorya ng mga problema — timeout sa pag-upload ng malalaking file. Ang mga HTTP client ay may mga setting na readTimeout at connectTimeout na maaaring mag-activate sa matagal na pag-upload ng file na mas malaki sa 50-100 MB. Solusyon — taasan ang mga timeout para sa upload endpoints o gumamit ng chunked transfer encoding sa loob ng multipart. Sa mga mobile device, mahalaga rin na i-handle ang pagkaantala ng pag-upload at i-implement ang pagpapatuloy (resume) kung mawala ang koneksyon.
Pag-upload ng mga file sa pamamagitan ng multipart ay isa sa mga pinaka-mahina na endpoint ng web application. Maaaring mag-upload ang isang attacker ng executable script sa pamamagitan ng pagpapalit ng pangalan nito sa image.jpg. Dapat suriin ng server ang MIME type ng na-upload na file hindi ayon sa extension, kundi ayon sa nilalaman (magic bytes), limitahan ang mga pinapayagang uri, at i-scan ang mga file gamit ang antivirus. Inirerekomenda na i-save ang mga na-upload na file sa labas ng document-root ng web server at ihatid ang mga ito sa pamamagitan ng isang hiwalay na controller na may pagsusuri ng mga karapatan sa pag-access.
Mga Madalas Itanong
multipart/form-data ay nagpapadala ng bawat field ng form bilang isang hiwalay na block na may sariling mga header at sumusuporta sa binary files nang walang encoding. Ang application/x-www-form-urlencoded ay nag-eencode ng lahat ng data sa isang URI-compatible string (key=value&key2=value2) at hindi direktang sumusuporta sa mga file — dapat silang i-encode sa base64.
Ang HTTP protocol ay hindi nililimitahan ang laki ng multipart request, ngunit sa praktika, ang mga limitasyon ay itinakda ng server. Nginx bilang default ay naglilimita sa 1 MB, Apache — sa 2 MB, Spring Boot — sa 1 MB. Para mag-upload ng malalaking file, i-configure ang client_max_body_size (Nginx) o spring.servlet.multipart.max-file-size (Spring Boot) sa nais na halaga — halimbawa, 100 MB.
Oo, ang multipart/form-data ay sumusuporta sa maraming file sa isang request. Ang bawat file ay ipinapadala bilang isang hiwalay na bahagi na may sariling Content-Disposition at Content-Type. Ang mga HTML form ay gumagamit ng attribute na multiple para sa input type="file". Sa OkHttp, tinatawag ang addFormDataPart para sa bawat file, sa Alamofire — append para sa bawat file.
Boundary ay isang natatanging string na naghihiwalay sa mga bahagi ng compound request at nagpapahintulot sa server na matukoy kung saan nagtatapos ang isang bahagi at nagsisimula ang isa pa. Ito ay nabubuo ng client at tinukoy sa Content-Type header. Kung walang boundary, hindi maaaring paghiwalayin ng server ang multicomponent request sa mga indibidwal na field at file.
Huwag umasa sa extension ng file o Content-Type mula sa request — maaaring pekein ang mga ito ng attacker. Suriin ang MIME type sa pamamagitan ng magic bytes (unang bytes ng file): mga library ng Apache Tika sa Java, libmagic sa C/C++, command na file sa Linux, o built-in na tools ng frameworks — Files.probeContentType() sa Java, mimetypes sa Python.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din