Multipart Upload — mətn sahələri və ikili fayllar da daxil olmaqla, bir sorğuda bir neçə müxtəlif növ məlumat hissəsini ötürməyə imkan verən HTTP mexanizmidir. Hər bir hissə unikal sərhəd sətri ilə ayrılır və öz Content-Type başlığına malikdir. MDN Web Docs, 2025 məlumatına görə, multipart/form-data HTML formaları vasitəsilə faylları yükləmək üçün standart formatdır və veb və mobil tətbiqlərdə şəkillərin, sənədlərin və digər faylların serverə göndərilməsi üçün geniş istifadə olunur.
Əsas məqamlar
Multipart Upload — HTTP protokolu ilə məlumat ötürmə metodudur, burada sorğunun gövdəsi bir neçə məntiqi olaraq ayrılmış hissədən ibarətdir. Hər bir hissə müxtəlif növ məlumatlar ehtiva edə bilər: forma mətn sahəsi, ikili fayl, JSON obyekti və ya şəkil. Bütün hissələr bir POST sorğusunda paketlənir ki, bu da N ayrıca HTTP çağırışı göndərmək ehtiyacını aradan qaldırır. Multipart Upload veb formalarının və fayl yükləmə API-lərinin ayrılmaz hissəsidir.
Multipart formatı RFC 2046 spesifikasiyasında e-poçt mesajları üçün MIME standartının bir hissəsi olaraq təyin edilmiş, sonra isə RFC 1867-də HTTP üçün adaptasiya edilmişdir. Bu gün veb inkişafda demək olar ki, yalnız multipart/form-data istifadə olunur — faylları olan formalar üçün nəzərdə tutulmuş multipart alt növlərindən biri. Digər alt növlər — multipart/mixed (ixtiyari əlavələr üçün) və multipart/byteranges (faylların qismən yüklənməsi üçün) — daha az tətbiq olunur.
Multipartın sadə application/x-www-form-urlencoded-dan əsas fərqi ondadır ki, sonuncu bütün məlumatları URI-uyğun sətirə kodlayır və ikili faylları dəstəkləmir. Multipart/form-data isə əksinə, hər bir faylı orijinal ikili formada kodlamadan ötürür ki, bu da daha səmərəlidir və dəqiqliyi itirmir. Sorğu ölçüsü multipartda hissə başlıqları və sərhədlər üçün əlavə xərclər səbəbindən fayl ölçülərinin cəmindən cəmi 5-15% daha böyükdür.
Multipart Upload fayl yükləmə tələb olunan hər yerdə tətbiq olunur: sosial şəbəkələrdə avatarlar və profil şəkilləri, messencerlərdə əlavələr, CRM sistemlərində sənədlər, onlayn mağazalarda məhsul şəkilləri. Mobil tətbiqlərdə Multipart Upload media fayllarını serverə göndərmək üçün istifadə olunur — cihazın kamerasından fotolar, səs yazıları, video fraqmentlər. Cloudflare Research məlumatına görə, vebdəki bütün POST sorğularının təxminən 15%-i multipart/form-data istifadə edir.
Multipart Upload və Chunked Transfer fərqli mexanizmlərdir. Multipart sorğunu mənalı hissələrə (sahələr və fayllar) bölür, Chunked Transfer isə ümumi ölçüsü bilmədən ötürmək üçün məlumat axınını fraqmentlərə bölür. Multipart Chunked Transfer daxilində ötürülə bilər: server tam həcmini bilmədən multipart cavabını hissə-hissə göndərir. Bu mexanizmlər ziddiyyət təşkil etmir və müxtəlif səviyyələrdə fərqli vəzifələri həll edir.
Brauzer enctype="multipart/form-data" atributu olan formanı göndərdikdə, sorğunun gövdəsini multipart formatında qurur. Formanın hər bir sahəsi ayrı bir bloka çevrilir, digərlərindən sərhəd sətri (boundary) ilə ayrılır. Sərhəd avtomatik yaradılır və məlumatların daxilində rast gəlinməyəcəyinə zəmanət verilən unikal simvol ardıcıllığıdır. Kliyent bu sərhədi Content-Type başlığına əlavə edir: multipart/form-data; boundary=----WebKitFormBoundaryX7K.
Hər bir blok --boundary ilə başlayır və sahə adı (name) və fayllar üçün orijinal fayl adı (filename) ilə Content-Disposition başlıqlarını ehtiva edir. Boş sətirdən sonra birbaşa sahə məlumatları və ya faylın ikili formada məzmunu gəlir. Sorğu --boundary-- sətri ilə bitir. Server alınan axını təhlil edir: əvvəlcə sərhədi tapır, sonra hər hissənin başlıqlarını çıxarır, məlumat növünü müəyyənləşdirir və onları forma emalçısına və ya API nəzarətçisinə ötürür.
IETF RFC 7578-ə görə, multipart/form-data hər hissə üçün charset təyin etməyi tələb etmir, çünki mətn sahələri UTF-8-də, ikili hissələr isə orijinal kodlaşdırmada faylları ehtiva edir. Bir hissənin ölçüsü protokolla məhdudlaşdırılmır — məhdudiyyətlər server səviyyəsində konfiqurasiya edilir: məsələn, Nginxdə client_max_body_size, Spring Boot-da spring.servlet.multipart.max-file-size vasitəsilə.
Boundary — ötürülən məlumatlarda rast gəlinməməli olan unikal sətirdir. Adətən prefikslə başlayır (məsələn, ----WebKitFormBoundary və ya ----Boundary) və təsadüfi simvollar ehtiva edir. Brauzerlər və HTTP kliyentləri boundary-ni avtomatik yaradır. RFC 2046-ya görə boundary-nin uzunluğu 70 simvoldan çox olmamalıdır. Hər bir hissə --boundary\r\n sətri ilə ayrılır, sorğunun sonu isə --boundary--\r\n sətri ilə göstərilir.
Multipart sorğu MIME və HTTP standartları ilə müəyyən edilmiş ciddi struktura malikdir. Sorğu başlığı boundary parametri ilə Content-Type: multipart/form-data təyin edir. Sorğunun gövdəsi ardıcıl hissələrdən ibarətdir, hər biri öz başlıqlarını və gövdəsini ehtiva edir. Hissə başlıqları Content-Disposition (məcburi) və Content-Type (isteğe bağlı — fayllar üçün) daxildir. Hissə başlıqları ilə onun məlumatları arasında boş sətir olmalıdır.
| Element | Nümunə | Məcburilik |
|---|---|---|
| Content-Type | multipart/form-data; boundary=---Bnd123 | Bəli |
| Hissə ayırıcısı | ---Bnd123 | Bəli (hər hissədən əvvəl) |
| Content-Disposition | form-data; name="avatar"; filename="photo.jpg" | Bəli |
| Hissənin Content-Type-ı | image/jpeg | Fayllar üçün |
| Hissənin gövdəsi | [şəklin ikili məlumatları] | Bəli |
| Bitmə sərhədi | ---Bnd123-- | Bəli (sorğunun sonu) |
Mətn sahəsi və şəkil faylı göndərən real multipart sorğu nümunəsini nəzərdən keçirək. Kliyent unikal boundary ilə Content-Type başlığı yaradır. Sorğunun gövdəsi ardıcıl olaraq formanın bütün sahələrini ehtiva edir. Server qəbul edərkən bu hissələri təhlil edir və proqramçıya hər bir sahəyə ayrıca obyekt kimi giriş imkanı verir. Bu yanaşma faylları olan mürəkkəb formaları bir HTTP çağırışında emal etməyə imkan verir.
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("Yükləndi: ${response.isSuccessful}")
}
}
Server tərəfində multipart sorğu framework tərəfindən və ya əl ilə təhlil edilir. Spring Boot-da @RequestParam("avatar") MultipartFile file annotasiyası kifayətdir və framework avtomatik olaraq faylı multipart sorğusundan çıxarır. Kotlində Ktor-da receiveMultipart(), Express.js-də multer middleware istifadə olunur. Server forma sahələrinin və yüklənmiş faylların hər birinə müstəqil giriş əldə edir, faylı diskdə və ya bulud anbarında saxlayır və kliyentə URL və ya identifikator qaytarır.
Multipart Upload alternativ məlumat ötürmə üsulları ilə müqayisədə bir neçə əsas üstünlük təmin edir. Çoxsaylı əvəzinə bir sorğu — forma sahələri və faylların hamısı bir HTTP çağırışında ötürülür ki, bu da şəbəkə və server yükünü azaldır. N faylı yükləmək üçün N əlaqə açmaq lazım deyil — hər şey bir POST-da paketlənir. Bu, xüsusilə hər HTTP əlaqəsinin gecikmə və batareya sərfiyyatı demək olduğu mobil tətbiqlər üçün vacibdir.
Kodlamasız ikili ötürmə — application/x-www-form-urlencoded-dən fərqli olaraq, ikili məlumatların base64-də kodlandığı (ölçü 33% artır), multipart/form-data faylları orijinal ikili formada ötürür. Bu, ölçü və sürət baxımından daha səmərəlidir. 10 MB-dan böyük fayllar üçün fərq kritik olur: multipart sorğu eyni fayl ilə URL-encoded sorğudan 30% daha kiçik olacaq.
İxtiyari struktur — multipart müxtəlif növ sahələri istənilən ardıcıllıqda birləşdirməyə imkan verir. Forma eyni anda mətn sahələri, bir neçə fayl, JSON məlumatları və gizli sahələr ehtiva edə bilər. Hər bir hissə öz Content-Type-na malikdir ki, bu da mətn və ikili məlumatları qarışdırmağa imkan verir. Müqayisə üçün: base64 kodlaması ölçüyə 33% əlavə edir, multipart isə xidməti başlıqlar üçün cəmi 5-15% əlavə edir.
HTTP Archive, 2025 tədqiqatına görə, multipart/form-data vebdə fayl yükləmələrinin 94% hallarında istifadə olunur. Alternativlər — JSON-da base64 (4%) və WebSocket vasitəsilə birbaşa ötürmə (2%). JSON ilə base64 digər məlumatların da JSON-da olduğu API-lər üçün əlverişlidir, lakin böyük fayllar üçün səmərəsizdir. WebSocket real vaxt rejimi üçün uyğundur, lakin bütün HTTP infrastrukturları tərəfindən dəstəklənmir. Multipart sadəliyi və səmərəliliyi sayəsində fayl yükləmə üçün standart olaraq qalır.
Mobil tətbiqlərdə Multipart Upload istifadəçi cihazlarından media məzmunu göndərmək üçün istifadə olunur: qalereyadan fotolar, kameradan çəkilmiş şəkillər, səs yazıları, sənəd faylları. Android-də standart üsul — MultipartBody.Builder ilə OkHttp-dur, bu da multipart sorğularını asanlıqla formalaşdırmağa imkan verir. Retrofit də @Multipart və @Part annotasiyaları vasitəsilə multipartı dəstəkləyir. Proqramçı hər hissə üçün məlumat növünü təyin edir, HTTP kliyenti avtomatik olaraq düzgün başlıqları yaradır.
iOS-da eyni vəzifələr URLSession ilə fərdi HTTPBodyStream və ya Alamofire ilə multipartFormData vasitəsilə həll edilir. Alamofire multipart sorğuları göndərmək üçün rahat upload(multipartFormData:) metodu təqdim edir. Hər iki platformada yüklənən faylların ölçüsünü nəzərə almaq vacibdir — böyük fayllar (10-20 MB-dan çox) üçün tətbiqin bağlanmasının qarşısını almaq üçün fon yükləmədən istifadə etmək tövsiyə olunur. Android-də bunun üçün DownloadManager və ya WorkManager, iOS-da — background konfiqurasiyası ilə URLSession istifadə olunur.
Mobil tətbiqlərdə faylları yükləyərkən şəbəkə vəziyyətini nəzərə almaq lazımdır. Connectivity Manager Android-də Wi-Fi və ya mobil məlumatın mövcud olub-olmadığını müəyyən etməyə və yükləmə üçün optimal anı seçməyə kömək edir. Video kimi böyük fayllar üçün istifadəçinin mobil trafikini sərf etməmək məqsədilə yükləməni Wi-Fi-a qoşulana qədər təxirə salmaq tövsiyə olunur. Android-də WorkManager NetworkType.UNMETERED vasitəsilə belə məhdudiyyətləri konfiqurasiya etməyə imkan verir.
Faylı Multipart Upload vasitəsilə göndərməzdən əvvəl mobil tətbiqlər tez-tez şəkli sıxışdırır və ölçüsünü dəyişdirir. JPEG sıxlaşdırması 85% keyfiyyətlə fayl ölçüsünü ekranda baxış üçün nəzərə çarpan keyfiyyət itkisi olmadan 3-5 dəfə azaldır. Şəklin uzun tərəfi 1920px-ə qədər ölçüsünün dəyişdirilməsi ölçüsünü daha da azaldır. Android-də bunun üçün Bitmap.compress(), iOS-da — UIImageJPEGRepresentation 0.85 sıxlaşdırma parametri ilə istifadə olunur. Belə optimallaşdırma yükləməni sürətləndirir və mobil trafikə qənaət edir.
Multipart Upload zamanı ən çox rast gəlinən səhv serverdə sorğu ölçüsü limitinin aşılmasıdır. Nginx standart olaraq sorğu gövdəsinin ölçüsünü 1 MB (client_max_body_size), Tomcat isə 2 MB (maxSwallowSize) ilə məhdudlaşdırır. Proqramçı bu limitləri artırmazsa, server 413 Request Entity Too Large xətası qaytaracaq. Həll yolu — serverdə maksimum yükləmə ölçüsünü açıq şəkildə konfiqurasiya etmək və kliyentdə fayl icazə verilən ölçüdən böyükdürsə xəbərdarlıq göstərməkdir.
İkinci problem — gövdənin axınla ötürülməsi zamanı multipart sorğularının düzgün emal edilməməsidir. Bəzi serverlər təhlildən əvvəl bütün multipart sorğusunu yaddaşa yükləməyə çalışır ki, bu da böyük fayllar üçün OutOfMemoryError-a səbəb olur. Müasir serverlər (Nginx, Spring Boot, Ktor) hər hissənin daxil olduqca emal edildiyi axınla multipart təhlilini dəstəkləyir. Proqramçı serverin axınla emal üçün konfiqurasiya edildiyinə əmin olmalıdır.
Üçüncü kateqoriya problemlər — böyük faylları yükləyərkən vaxt aşımı. HTTP kliyentlərinin readTimeout və connectTimeout parametrləri var ki, bunlar 50-100 MB-dan böyük faylın uzun müddətli yüklənməsi zamanı işə düşə bilər. Həll yolu — yükləmə endpointləri üçün vaxt aşımlarını artırmaq və ya multipart daxilində chunked transfer encoding istifadə etməkdir. Mobil cihazlarda yükləmənin kəsilməsini emal etmək və əlaqə itkisi zamanı bərpanı (resume) tətbiq etmək də vacibdir.
Faylların yüklənməsi multipart vasitəsilə veb tətbiqinin ən həssas endpointlərindən biridir. Təcavüzkar adını image.jpg olaraq dəyişdirərək icra olunan skript yükləyə bilər. Server yüklənən faylın MIME növünü genişlənməsinə görə deyil, məzmununa görə (magic bytes) yoxlamalı, icazə verilən növləri məhdudlaşdırmalı və faylları antivirusla skan etməlidir. Yüklənmiş faylları veb serverin document-rootundan kənarda saxlamaq və onları ayrıca giriş hüquqlarının yoxlanılması ilə nəzarətçi vasitəsilə təqdim etmək tövsiyə olunur.
Tez-tez verilən suallar
multipart/form-data forma sahələrinin hər birini öz başlıqları ilə ayrıca blok kimi ötürür və kodlamadan ikili faylları dəstəkləyir. application/x-www-form-urlencoded bütün məlumatları URI-uyğun sətirə kodlayır (açar=dəyər&açar2=dəyər2) və faylları birbaşa dəstəkləmir — onları base64-də kodlamaq lazımdır.
HTTP protokolu multipart sorğusunun ölçüsünü məhdudlaşdırmır, lakin praktikada limitlər server tərəfindən təyin edilir. Nginx standart olaraq 1 MB, Apache — 2 MB, Spring Boot — 1 MB ilə məhdudlaşdırır. Böyük faylları yükləmək üçün client_max_body_size (Nginx) və ya spring.servlet.multipart.max-file-size (Spring Boot) parametrini lazımi dəyərə — məsələn, 100 MB-a təyin edin.
Bəli, multipart/form-data bir sorğuda çoxsaylı faylları dəstəkləyir. Hər bir fayl öz Content-Disposition və Content-Type ilə ayrıca hissə kimi ötürülür. HTML formaları input type="file" üçün multiple atributundan istifadə edir. OkHttp-da bunun üçün hər fayl üçün addFormDataPart çağırılır, Alamofire-da — hər fayl üçün append.
Boundary — mürəkkəb sorğunun hissələrini ayıran və serverə bir hissənin harada bitib digərinin harada başladığını müəyyən etməyə imkan verən unikal sətirdir. Kliyent tərəfindən yaradılır və Content-Type başlığında göstərilir. Boundary olmadan server çoxkomponentli sorğunu ayrıca sahələrə və fayllara ayıra bilməz.
Faylın genişlənməsinə və ya sorğudakı Content-Type-a etibar etməyin — təcavüzkar onları saxtalaşdıra bilər. MIME növünü magic bytes (faylın ilk baytları) vasitəsilə yoxlayın: Java-da Apache Tika kitabxanaları, C/C++-da libmagic, Linux-da file əmri və ya framework-lərin daxili vasitələri — Java-da Files.probeContentType(), Python-da mimetypes.
Nəticə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun