Multipart Upload în dezvoltarea web: esența, structura și cum funcționează multipart/form-data

Autor: IT Sectr Publicat: 2026-03-10 Timp de citire: 9 min

Multipart Upload este un mecanism HTTP care permite transmiterea mai multor părți eterogene de date într-o singură cerere, inclusiv câmpuri text și fișiere binare. Fiecare parte este separată de un șir delimitator unic și are propriul antet Content-Type. Conform MDN Web Docs, 2025, multipart/form-data este formatul standard pentru încărcarea fișierelor prin formulare HTML și este utilizat pe scară largă în aplicațiile web și mobile pentru trimiterea de imagini, documente și alte fișiere către server.

Principalele puncte

  • Multipart Upload — transmiterea mai multor părți de date într-o singură cerere HTTP cu separare prin boundary.
  • multipart/form-data — tipul MIME standard pentru încărcarea fișierelor din formulare HTML și aplicații mobile.
  • Boundary — șir unic care separă părțile unei cereri compuse, generat automat de clienții HTTP.
  • Fiecare parte conține antetele Content-Disposition și Content-Type care descriu numele câmpului și tipul fișierului.
  • Multipart Upload este mai eficient decât cererile multiple — un singur POST înlocuiește N apeluri separate către server.

Ce este Multipart Upload?

Multipart Upload este o metodă de transmitere a datelor prin protocolul HTTP, în care corpul cererii constă din mai multe părți separate logic. Fiecare parte poate conține date de tip diferit: un câmp text de formular, un fișier binar, un obiect JSON sau o imagine. Toate părțile sunt împachetate într-o singură cerere POST, ceea ce înlocuiește necesitatea de a trimite N apeluri HTTP separate. Multipart Upload este o parte integrantă a formularelor web și a API-urilor pentru încărcarea fișierelor.

Formatul multipart a fost definit în specificația RFC 2046 ca parte a standardului MIME pentru mesajele de e-mail, apoi adaptat pentru HTTP în RFC 1867. Astăzi, în dezvoltarea web se utilizează aproape exclusiv multipart/form-data — unul dintre subtipurile multipart, destinat formularelor care conțin fișiere. Alte subtipuri — multipart/mixed (pentru atașamente arbitrare) și multipart/byteranges (pentru încărcarea parțială a fișierelor) — sunt folosite mult mai rar.

Diferența fundamentală dintre multipart și simplul application/x-www-form-urlencoded este că acesta din urmă codifică toate datele într-un șir compatibil URI și nu suportă fișiere binare. Multipart/form-data, dimpotrivă, transmite fiecare fișier în forma sa binară originală fără codificare, ceea ce este mai eficient și nu pierde precizie. Dimensiunea cererii la multipart este doar cu 5-15% mai mare decât suma dimensiunilor fișierelor din cauza cheltuielilor suplimentare pentru antetele părților și delimitatori.

Când se utilizează Multipart Upload

Multipart Upload se aplică oriunde este necesară încărcarea fișierelor: avataruri și fotografii de profil în rețelele sociale, atașamente în mesagerie, documente în sisteme CRM, imagini ale produselor în magazinele online. În aplicațiile mobile, Multipart Upload este utilizat pentru trimiterea fișierelor media către server — fotografii de pe camera dispozitivului, înregistrări vocale, fragmente video. Conform datelor Cloudflare Research, aproximativ 15% din toate cererile POST din web utilizează multipart/form-data.

Diferența dintre multipart și chunked transfer

Multipart Upload și Chunked Transfer sunt mecanisme diferite. Multipart împarte cererea în părți cu conținut (câmpuri și fișiere), în timp ce Chunked Transfer împarte fluxul de date în fragmente pentru transmitere fără cunoașterea dimensiunii totale. Multipart poate fi transmis în interiorul Chunked Transfer: serverul trimite răspunsul multipart pe bucăți, fără a cunoaște volumul său total. Aceste mecanisme nu sunt în conflict și rezolvă sarcini diferite la niveluri diferite.

Cum funcționează multipart/form-data

Când browserul trimite un formular cu atributul enctype="multipart/form-data", acesta construiește corpul cererii în format multipart. Fiecare câmp al formularului devine un bloc separat, delimitat de celelalte printr-un șir graniță (boundary). Granița este generată automat și reprezintă o secvență unică de caractere care se garantează că nu apare în interiorul datelor. Clientul adaugă această graniță în antetul Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryX7K.

Fiecare bloc începe cu --boundary și conține antetele Content-Disposition cu numele câmpului (name) și, pentru fișiere, numele original al fișierului (filename). După o linie goală urmează direct datele câmpului sau conținutul fișierului în formă binară. Cererea se termină cu șirul --boundary--. Serverul analizează fluxul primit: mai întâi găsește granița, apoi extrage antetele fiecărei părți, determină tipul de date și le transmite handler-ului de formular sau controlerului API.

Conform IETF RFC 7578, multipart/form-data nu necesită specificarea charset pentru fiecare parte, deoarece câmpurile text sunt considerate UTF-8, iar părțile binare conțin fișiere în codificarea lor originală. Dimensiunea unei părți nu este limitată de protocol — limitările sunt configurate la nivelul serverului: de exemplu, în Nginx prin client_max_body_size, în Spring Boot prin spring.servlet.multipart.max-file-size.

Formatul boundary și generarea sa

Boundary este un șir unic care nu trebuie să apară în datele transmise. De obicei, începe cu un prefix (de exemplu, ----WebKitFormBoundary sau ----Boundary) și conține caractere aleatorii. Browserele și clienții HTTP generează boundary automat. Lungimea boundary nu trebuie să depășească 70 de caractere conform RFC 2046. Fiecare parte este separată prin șirul --boundary\r\n, iar sfârșitul cererii — prin șirul --boundary--\r\n.

Structura cererii multipart

Cererea multipart are o structură strictă definită de standardele MIME și HTTP. Antetul cererii stabilește Content-Type: multipart/form-data cu parametrul boundary. Corpul cererii constă dintr-o succesiune de părți, fiecare conținând propriile antete și corp. Antetele părții includ Content-Disposition (obligatoriu) și Content-Type (opțional — pentru fișiere). Este obligatorie prezența unei linii goale între antetele părții și datele sale.

ElementExempluObligatoriu
Content-Typemultipart/form-data; boundary=---Bnd123Da
Delimitator de parte---Bnd123Da (înaintea fiecărei părți)
Content-Dispositionform-data; name="avatar"; filename="photo.jpg"Da
Content-Type al părțiiimage/jpegPentru fișiere
Corpul părții[date binare ale imaginii]Da
Granita finală---Bnd123--Da (sfârșitul cererii)

Exemplu de cerere multipart

Să examinăm un exemplu real de cerere multipart care trimite un câmp text și un fișier imagine. Clientul formează antetul Content-Type cu un boundary unic. Corpul cererii conține succesiv toate câmpurile formularului. Serverul, la primire, analizează aceste părți și oferă dezvoltatorului acces la fiecare câmp ca la un obiect separat. Această abordare permite procesarea formularelor complexe cu fișiere într-un singur apel HTTP.

kotlin
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("Încărcat: ${response.isSuccessful}")
    }
}

Analiza răspunsului multipart pe server

Pe partea serverului, cererea multipart este analizată de framework sau manual. În Spring Boot, este suficientă adnotarea @RequestParam("avatar") MultipartFile file, iar framework-ul extrage automat fișierul din cererea multipart. În Ktor pe Kotlin se utilizează receiveMultipart(), în Express.js — middleware-ul multer. Serverul obține acces la fiecare câmp al formularului și la fiecare fișier încărcat independent, salvează fișierul pe disc sau în stocare cloud și returnează clientului URL-ul sau identificatorul.

Avantajele încărcării multicomponente

Multipart Upload oferă câteva avantaje cheie față de metodele alternative de transmitere a datelor. O singură cerere în loc de mai multe — toate câmpurile formularului și fișierele sunt transmise într-un singur apel HTTP, ceea ce reduce încărcarea rețelei și a serverului. Nu este nevoie să deschideți N conexiuni pentru a încărca N fișiere — totul este împachetat într-un singur POST. Acest lucru este deosebit de important pentru aplicațiile mobile, unde fiecare conexiune HTTP înseamnă întârziere și consum de baterie.

Transmitere binară fără codificare — spre deosebire de application/x-www-form-urlencoded, unde datele binare sunt codificate în base64 (creștere a dimensiunii cu 33%), multipart/form-data transmite fișierele în forma lor binară originală. Acest lucru este mai eficient ca dimensiune și viteză. Pentru fișierele mari de la 10 MB în sus, diferența devine critică: cererea multipart va fi cu 30% mai mică decât o cerere URL-encoded cu același fișier.

Structură arbitrară — multipart permite combinarea câmpurilor de diferite tipuri în orice ordine. Formularul poate conține simultan câmpuri text, mai multe fișiere, date JSON și câmpuri ascunse. Fiecare parte are propriul Content-Type, ceea ce permite amestecarea datelor text și binare. Pentru comparație: codificarea base64 adaugă 33% la dimensiune, iar multipart doar aproximativ 5-15% pentru antetele de serviciu.

Comparația multipart cu alte formate de transmitere

Conform studiului HTTP Archive, 2025, multipart/form-data este utilizat în 94% din cazurile de încărcare a fișierelor în web. Alternative — base64 în JSON (4%) și transmiterea directă prin WebSocket (2%). JSON cu base64 este convenabil pentru API-urile unde toate celelalte date sunt și ele în JSON, dar ineficient pentru fișiere mari. WebSocket este potrivit pentru timp real, dar nu este suportat de toate infrastructurile HTTP. Multipart rămâne standardul pentru încărcarea fișierelor datorită simplității și eficienței sale.

Multipart Upload în dezvoltarea mobilă

În aplicațiile mobile, Multipart Upload este utilizat pentru trimiterea conținutului media de pe dispozitivele utilizatorilor: fotografii din galerie, imagini de la cameră, înregistrări vocale, fișiere documente. Pe Android, metoda standard este OkHttp cu MultipartBody.Builder, care permite formarea ușoară a cererilor multipart. Retrofit suportă de asemenea multipart prin adnotările @Multipart și @Part. Dezvoltatorul specifică tipul de date pentru fiecare parte, iar clientul HTTP generează automat antetele corecte.

Pe iOS, aceleași sarcini sunt rezolvate prin URLSession cu HTTPBodyStream personalizat sau prin Alamofire cu multipartFormData. Alamofire oferă metoda convenabilă upload(multipartFormData:) pentru trimiterea cererilor multipart. Pe ambele platforme este important să se ia în considerare dimensiunea fișierelor încărcate — pentru fișierele mari (peste 10-20 MB) se recomandă utilizarea încărcării în fundal, pentru ca aplicația să nu se închidă la minimizare. Pe Android se folosește DownloadManager sau WorkManager, pe iOS — URLSession cu configurare background.

La încărcarea fișierelor în aplicațiile mobile, trebuie să se țină cont de starea rețelei. Connectivity Manager pe Android ajută la determinarea dacă este disponibil Wi-Fi sau date mobile și la alegerea momentului optim pentru încărcare. Pentru fișierele mari, cum ar fi videoclipurile, se recomandă amânarea încărcării până la conectarea la Wi-Fi, pentru a nu consuma traficul mobil al utilizatorului. WorkManager pe Android permite configurarea unor astfel de restricții prin NetworkType.UNMETERED.

Optimizarea încărcării: compresie și redimensionare

Înainte de trimiterea fișierului prin Multipart Upload, aplicațiile mobile deseori comprimă și redimensionează imaginea. Compresia JPEG cu calitate de 85% reduce dimensiunea fișierului de 3-5 ori fără pierdere vizibilă de calitate pentru vizualizare pe ecran. Redimensionarea imaginii la 1920px pe latura mai mare reduce suplimentar dimensiunea. Pe Android se folosește Bitmap.compress(), pe iOS — UIImageJPEGRepresentation cu parametrul de compresie 0.85. O astfel de optimizare accelerează încărcarea și economisește traficul mobil.

Erori și limitări ale Multipart Upload

Cea mai frecventă eroare la Multipart Upload — depășirea limitei de dimensiune a cererii pe server. În mod implicit, Nginx limitează dimensiunea corpului cererii la 1 MB (client_max_body_size), iar Tomcat — la 2 MB (maxSwallowSize). Dacă dezvoltatorul nu mărește aceste limite, serverul va returna eroarea 413 Request Entity Too Large. Soluția — configurarea explicită a dimensiunii maxime de încărcare pe server și afișarea unei avertizări pe client dacă fișierul depășește dimensiunea permisă.

A doua problemă — procesarea incorectă a cererilor multipart la streamingul corpului. Unele servere încearcă să încarce întreaga cerere multipart în memorie înainte de analiză, ceea ce duce la OutOfMemoryError pentru fișierele mari. Servere moderne (Nginx, Spring Boot, Ktor) suportă analiza în flux a multipart, când fiecare parte este procesată pe măsură ce sosește. Dezvoltatorul trebuie să se asigure că serverul este configurat pentru procesarea în flux a cererilor multipart.

A treia categorie de probleme — timeout-uri la încărcarea fișierelor mari. Clienții HTTP au setările readTimeout și connectTimeout care se pot declanșa la încărcarea prelungită a unui fișier mai mare de 50-100 MB. Soluția — mărirea timeout-urilor pentru endpoint-urile de încărcare sau utilizarea chunked transfer encoding în interiorul multipart. Pe dispozitivele mobile este de asemenea important să se gestioneze întreruperea încărcării și să se implementeze reluarea (resume) în cazul pierderii conexiunii.

Securitatea Multipart Upload

Încărcarea fișierelor prin multipart este unul dintre cele mai vulnerabile endpoint-uri ale aplicației web. Un atacator poate încărca un script executabil, redenumindu-l în image.jpg. Serverul trebuie să verifice tipul MIME al fișierului încărcat nu după extensie, ci după conținut (magic bytes), să limiteze tipurile permise și să scaneze fișierele cu antivirus. Se recomandă salvarea fișierelor încărcate în afara document-root-ului serverului web și livrarea lor printr-un controler separat cu verificarea drepturilor de acces.

Întrebări frecvente

Cu ce se deosebește multipart/form-data de application/x-www-form-urlencoded?

multipart/form-data transmite fiecare câmp al formularului ca un bloc separat cu propriile antete și suportă fișiere binare fără codificare. application/x-www-form-urlencoded codifică toate datele într-un șir compatibil URI (cheie=valoare&cheie2=valoare2) și nu suportă fișiere direct — acestea trebuie codificate în base64.

Care este dimensiunea maximă a fișierului pentru Multipart Upload?

Protocolul HTTP nu limitează dimensiunea cererii multipart, dar în practică limitele sunt stabilite de server. Nginx în mod implicit limitează la 1 MB, Apache — la 2 MB, Spring Boot — la 1 MB. Pentru încărcarea fișierelor mari, configurați client_max_body_size (Nginx) sau spring.servlet.multipart.max-file-size (Spring Boot) la valoarea dorită — de exemplu, 100 MB.

Se pot transmite mai multe fișiere într-o singură cerere multipart?

Da, multipart/form-data suportă mai multe fișiere într-o singură cerere. Fiecare fișier este transmis ca o parte separată cu propriul Content-Disposition și Content-Type. Formularele HTML folosesc atributul multiple pentru input type="file". În OkHttp se apelează addFormDataPart pentru fiecare fișier, în Alamofire — append pentru fiecare fișier.

De ce este necesar boundary-ul într-o cerere multipart?

Boundary este un șir unic care separă părțile cererii compuse și permite serverului să determine unde se termină o parte și începe alta. Este generat de client și specificat în antetul Content-Type. Fără boundary, serverul nu poate separa cererea multicomponentă în câmpuri și fișiere individuale.

Cum se verifică tipul fișierului încărcat pe server?

Nu vă bazați pe extensia fișierului sau pe Content-Type din cerere — un atacator le poate falsifica. Verificați tipul MIME prin magic bytes (primii octeți ai fișierului): bibliotecile Apache Tika în Java, libmagic în C/C++, comanda file în Linux, sau instrumentele încorporate ale framework-urilor — Files.probeContentType() în Java, mimetypes în Python.

Rezumat

  • Multipart Upload — mecanism de transmitere a mai multor părți eterogene într-o singură cerere HTTP cu separare prin boundary.
  • multipart/form-data — tipul MIME standard pentru încărcarea fișierelor prin formulare web și aplicații mobile, suportă transmiterea binară fără codificare.
  • Fiecare parte a cererii conține propriile antete Content-Disposition și Content-Type, permițând transmiterea câmpurilor de diferite tipuri într-o singură cerere.
  • Boundary — șir delimitator unic, generat automat de client și care nu trebuie să apară în datele transmise.
  • Avantaje — o singură cerere în loc de mai multe, transmitere binară fără codificare base64, suport pentru fișiere de orice dimensiune (cu configurarea corectă a serverului).
  • Limitări — limite de dimensiune pe server, timeout-uri la încărcarea fișierelor mari, risc de OutOfMemoryError fără procesare în flux.
  • Securitate — verificați tipul MIME după conținutul fișierului, nu după extensie, salvați fișierele în afara document-root și scanați-le cu antivirus.

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și