Multipart Upload, metin alanları ve ikili dosyalar dahil olmak üzere birden çok heterojen veri parçasını tek bir istekte aktarmaya olanak tanıyan bir HTTP mekanizmasıdır. Her parça benzersiz bir sınır dizesiyle ayrılır ve kendi Content-Type başlığına sahiptir. MDN Web Docs, 2025'e göre, multipart/form-data HTML formları aracılığıyla dosya yüklemek için standart biçimdir ve web ve mobil uygulamalarda görüntüleri, belgeleri ve diğer dosyaları sunucuya göndermek için yaygın olarak kullanılır.
Önemli Noktalar
Multipart Upload, istek gövdesinin birden çok mantıksal olarak ayrılmış parçadan oluştuğu HTTP protokolü aracılığıyla bir veri aktarım yöntemidir. Her parça farklı türde veri içerebilir: bir metin form alanı, ikili bir dosya, bir JSON nesnesi veya bir görüntü. Tüm parçalar tek bir POST isteğinde paketlenir ve N ayrı HTTP çağrısı gönderme ihtiyacını ortadan kaldırır. Multipart Upload, web formlarının ve dosya yükleme API'lerinin önemli bir parçasıdır.
Multipart biçimi, e-posta mesajları için MIME standardının bir parçası olarak RFC 2046 spesifikasyonunda tanımlanmış ve daha sonra RFC 1867'de HTTP'ye uyarlanmıştır. Günümüzde web geliştirme, dosya içeren formlar için tasarlanmış multipart alt türlerinden biri olan multipart/form-data'yı neredeyse tamamen kullanmaktadır. Diğer alt türler — multipart/mixed (rastgele ekler için) ve multipart/byteranges (dosyaların kısmi indirilmesi için) — çok daha az sıklıkla kullanılır.
Multipart ile basit application/x-www-form-urlencoded arasındaki temel fark, ikincisinin tüm verileri URI uyumlu bir dizeye kodlaması ve ikili dosyaları desteklememesidir. Multipart/form-data ise her dosyayı kodlama olmadan orijinal ikili biçiminde iletir, bu da daha verimlidir ve hassasiyet kaybına neden olmaz. İstek boyutu, multipart ile parça başlıkları ve sınırların ek yükü nedeniyle dosya boyutlarının toplamından her zaman %5-15 daha büyüktür.
Multipart Upload, dosya yüklemesi gereken her yerde kullanılır: sosyal ağlarda avatarlar ve profil fotoğrafları, mesajlaşma uygulamalarında ekler, CRM sistemlerinde belgeler, çevrimiçi mağazalarda ürün görselleri. Mobil uygulamalarda, Multipart Upload, medya dosyalarını sunucuya göndermek için kullanılır — cihaz kamerasından fotoğraflar, ses kayıtları, video klipleri. Cloudflare Research'e göre, web'deki tüm POST isteklerinin yaklaşık %15'i multipart/form-data kullanır.
Multipart Upload ve Parçalı Aktarım (Chunked Transfer) farklı mekanizmalardır. Multipart, bir isteği anlamlı parçalara (alanlar ve dosyalar) ayırırken, Parçalı Aktarım, toplam boyutu bilmeden iletim için bir veri akışını parçalara ayırır. Multipart, Parçalı Aktarım içinde iletilebilir: sunucu, tam boyutunu bilmeden bir multipart yanıtını parçalar halinde gönderir. Bu mekanizmalar çakışmaz ve farklı seviyelerde farklı sorunları çözer.
Bir tarayıcı enctype="multipart/form-data" özniteliğine sahip bir form gönderdiğinde, istek gövdesini multipart biçiminde oluşturur. Her form alanı, bir sınır dizesi (boundary) ile diğerlerinden ayrılan ayrı bir blok haline gelir. Sınır otomatik olarak oluşturulur ve verilerin içinde görünmeyeceği garanti edilen benzersiz bir karakter dizisidir. İstemci bu sınırı Content-Type başlığına ekler: multipart/form-data; boundary=----WebKitFormBoundaryX7K.
Her blok --boundary ile başlar ve alan adını (name) ve dosyalar için orijinal dosya adını (filename) içeren Content-Disposition başlıklarını içerir. Boş bir satırdan sonra gerçek alan verileri veya ikili biçimde dosya içeriği gelir. İstek --boundary-- dizesiyle sona erer. Sunucu alınan akışı ayrıştırır: önce sınırı bulur, ardından her parçanın başlıklarını çıkarır, veri türünü belirler ve bunları form işleyicisine veya API denetleyicisine iletir.
IETF RFC 7578'e göre, multipart/form-data her parça için bir charset belirtilmesini gerektirmez, çünkü metin alanlarının UTF-8 olduğu varsayılır ve ikili parçalar dosyaları orijinal kodlamalarında içerir. Bir parçanın boyutu protokol tarafından sınırlandırılmamıştır — sınırlar sunucu düzeyinde belirlenir: örneğin, Nginx'te client_max_body_size ile, Spring Boot'ta spring.servlet.multipart.max-file-size ile.
Boundary, iletilen verilerde görünmemesi gereken benzersiz bir dizedir. Genellikle bir önekle (örneğin, ----WebKitFormBoundary veya ----Boundary) başlar ve rastgele karakterler içerir. Tarayıcılar ve HTTP istemcileri boundary'yi otomatik olarak oluşturur. RFC 2046'ya göre boundary uzunluğu 70 karakteri geçmemelidir. Her parça --boundary\r\n dizesiyle ayrılır ve isteğin sonu --boundary--\r\n ile işaretlenir.
Bir multipart isteği, MIME ve HTTP standartları tarafından tanımlanan katı bir yapıya sahiptir. İstek başlığı, bir boundary parametresiyle Content-Type: multipart/form-data olarak ayarlanır. İstek gövdesi, her biri kendi başlıklarına ve gövdesine sahip bir dizi parçadan oluşur. Parça başlıkları Content-Disposition (zorunlu) ve Content-Type (isteğe bağlı — dosyalar için) içerir. Parça başlıkları ile verileri arasında boş bir satır bulunması zorunludur.
| Öğe | Örnek | Zorunluluk |
|---|---|---|
| Content-Type | multipart/form-data; boundary=---Bnd123 | Evet |
| Parça ayırıcı | ---Bnd123 | Evet (her parçadan önce) |
| Content-Disposition | form-data; name="avatar"; filename="photo.jpg" | Evet |
| Parça Content-Type | image/jpeg | Dosyalar için |
| Parça gövdesi | [ikili görüntü verileri] | Evet |
| Bitiş sınırı | ---Bnd123-- | Evet (isteğin sonu) |
Bir metin alanı ve bir görüntü dosyası gönderen gerçek bir multipart isteği örneğini ele alalım. İstemci, benzersiz bir boundary ile Content-Type başlığını oluşturur. İstek gövdesi sırayla tüm form alanlarını içerir. Sunucu, alındığında bu parçaları ayrıştırır ve geliştiriciye her alana ayrı bir nesne olarak erişim sağlar. Bu yaklaşım, tek bir HTTP çağrısında dosyalarla karmaşık formların işlenmesine olanak tanır.
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üklendi: ${response.isSuccessful}")
}
}
Sunucu tarafında, multipart isteği çerçeve tarafından veya manuel olarak ayrıştırılır. Spring Boot'ta, @RequestParam("avatar") MultipartFile file notasyonu yeterlidir ve çerçeve otomatik olarak multipart isteğinden dosyayı çıkarır. Kotlin'de Ktor'da receiveMultipart() kullanılır, Express.js'de — multer ara yazılımı. Sunucu, her form alanına ve yüklenen her dosyaya bağımsız olarak erişir, dosyayı diske veya bulut depolamaya kaydeder ve istemciye bir URL veya tanımlayıcı döndürür.
Multipart Upload, alternatif veri aktarım yöntemlerine göre birkaç önemli avantaj sunar. Birçok yerine tek bir istek — tüm form alanları ve dosyalar tek bir HTTP çağrısında iletilir, bu da ağ ve sunucu yükünü azaltır. N dosyayı yüklemek için N bağlantı açmaya gerek yoktur — her şey tek bir POST'ta paketlenir. Bu, her HTTP bağlantısının gecikme ve pil tüketimi anlamına geldiği mobil uygulamalar için özellikle önemlidir.
Kodlama olmadan ikili aktarım — ikili verilerin base64 ile kodlandığı (boyutu %33 artıran) application/x-www-form-urlencoded'ın aksine, multipart/form-data dosyaları orijinal ikili biçimlerinde iletir. Bu, boyut ve hız açısından daha verimlidir. 10 MB'ın üzerindeki büyük dosyalar için fark kritik hale gelir: aynı dosyayla URL kodlu bir istekten multipart isteği %30 daha küçük olacaktır.
Rastgele yapı — multipart, farklı türdeki alanları herhangi bir sırada birleştirmeye olanak tanır. Bir form aynı anda metin alanları, birden çok dosya, JSON verileri ve gizli alanlar içerebilir. Her parça kendi Content-Type'ına sahiptir, bu da metin ve ikili verilerin karıştırılmasına olanak tanır. Karşılaştırma için: base64 kodlaması boyuta %33 eklerken, multipart hizmet başlıkları için yalnızca yaklaşık %5-15 ekler.
HTTP Archive, 2025 araştırmasına göre, web'deki dosya yükleme vakalarının %94'ünde multipart/form-data kullanılır. Alternatifler — JSON'da base64 (%4) ve WebSocket üzerinden doğrudan aktarım (%2). JSON ile base64, diğer tüm verilerin de JSON olduğu API'ler için uygundur, ancak büyük dosyalar için verimsizdir. WebSocket gerçek zamanlı veriler için uygundur ancak tüm HTTP altyapıları tarafından desteklenmez. Multipart, basitliği ve verimliliği sayesinde dosya yükleme için standart olmaya devam etmektedir.
Mobil uygulamalarda, Multipart Upload kullanıcı cihazlarından medya içeriği göndermek için kullanılır: galeriden fotoğraflar, kamera çekimleri, ses kayıtları, belge dosyaları. Android'de standart yaklaşım, MultipartBody.Builder ile OkHttp'dur ve multipart isteklerinin kolayca oluşturulmasını sağlar. Retrofit de @Multipart ve @Part notasyonları aracılığıyla multipart'ı destekler. Geliştirici her parça için veri türünü belirtir ve HTTP istemcisi otomatik olarak doğru başlıkları oluşturur.
iOS'te aynı görevler, özel HTTPBodyStream ile URLSession veya Alamofire ile multipartFormData aracılığıyla çözülür. Alamofire, multipart istekleri göndermek için kullanışlı bir upload(multipartFormData:) yöntemi sağlar. Her iki platformda da yüklenen dosyaların boyutunu dikkate almak önemlidir — büyük dosyalar (10-20 MB'ın üzerinde) için, uygulama simge durumuna küçültüldüğünde sonlanmaması için arka planda yükleme kullanılması önerilir. Android'de bu DownloadManager veya WorkManager ile, iOS'te — arka plan yapılandırmasıyla URLSession ile yapılır.
Mobil uygulamalarda dosya yüklerken ağ durumu dikkate alınmalıdır. Android'deki Connectivity Manager, Wi-Fi veya mobil verinin kullanılabilir olup olmadığını belirlemeye ve yükleme için en uygun zamanı seçmeye yardımcı olur. Video gibi büyük dosyalar için, kullanıcının mobil verisini tüketmemek amacıyla Wi-Fi'ye bağlanana kadar yüklemenin ertelenmesi önerilir. Android'de WorkManager, NetworkType.UNMETERED aracılığıyla bu tür kısıtlamaların ayarlanmasına olanak tanır.
Multipart Upload aracılığıyla bir dosya göndermeden önce, mobil uygulamalar genellikle görüntüyü sıkıştırır ve yeniden boyutlandırır. JPEG sıkıştırması %85 kalitede, ekranda görüntüleme için fark edilir kalite kaybı olmadan dosya boyutunu 3-5 kat azaltır. Görüntünün uzun kenarda 1920 piksele yeniden boyutlandırılması boyutu daha da azaltır. Android'de bunun için Bitmap.compress() kullanılır, iOS'te — 0,85 sıkıştırma parametresiyle UIImageJPEGRepresentation. Bu tür optimizasyon yüklemeyi hızlandırır ve mobil veri tasarrufu sağlar.
Multipart Upload'da en yaygın hata, sunucudaki istek boyutu sınırının aşılmasıdır. Varsayılan olarak, Nginx istek gövdesi boyutunu 1 MB (client_max_body_size) ile, Tomcat ise 2 MB (maxSwallowSize) ile sınırlar. Geliştirici bu sınırları artırmazsa, sunucu 413 Request Entity Too Large hatası döndürür. Çözüm, sunucuda maksimum yükleme boyutunu açıkça yapılandırmak ve dosya izin verilen boyutu aşarsa istemcide bir uyarı göstermektir.
İkinci sorun, gövde akışı sırasında multipart isteklerinin yanlış işlenmesidir. Bazı sunucular, ayrıştırmadan önce tüm multipart isteğini belleğe yüklemeye çalışır ve bu da büyük dosyalar için OutOfMemoryError'a yol açar. Modern sunucular (Nginx, Spring Boot, Ktor), her parçanın geldiğinde işlendiği akışlı multipart ayrıştırmayı destekler. Geliştirici, sunucunun multipart isteklerinin akışlı işlenmesi için yapılandırıldığından emin olmalıdır.
Üçüncü sorun kategorisi, büyük dosyalar yüklenirken zaman aşımlarıdır. HTTP istemcileri, 50-100 MB'ın üzerindeki dosyaların uzun yüklemeleri sırasında tetiklenebilecek readTimeout ve connectTimeout ayarlarına sahiptir. Çözüm, yükleme uç noktaları için zaman aşımlarını artırmak veya multipart içinde parçalı aktarım kodlaması kullanmaktır. Mobil cihazlarda, yükleme kesintisini ele almak ve bağlantı kaybı durumunda devam ettirme (resume) uygulamak da önemlidir.
Dosya yükleme (multipart aracılığıyla) bir web uygulamasının en savunmasız uç noktalarından biridir. Bir saldırgan, yürütülebilir bir betiği image.jpg olarak yeniden adlandırarak yükleyebilir. Sunucu, yüklenen dosyanın MIME türünü uzantıdan değil içerikten (sihirli baytlar) kontrol etmeli, izin verilen türleri sınırlamalı ve dosyaları antivirüs ile taramalıdır. Yüklenen dosyaların web sunucusunun document-root'unun dışında saklanması ve erişim hakları kontrolü olan ayrı bir denetleyici aracılığıyla sunulması önerilir.
Sıkça Sorulan Sorular
multipart/form-data her form alanını kendi başlıklarıyla ayrı bir blok olarak iletir ve kodlama olmadan ikili dosyaları destekler. application/x-www-form-urlencoded tüm verileri URI uyumlu bir dizeye (anahtar=değer&anahtar2=değer2) kodlar ve dosyaları doğrudan desteklemez — base64 ile kodlanmaları gerekir.
HTTP protokolü bir multipart isteğinin boyutunu sınırlamaz, ancak pratikte sınırlar sunucu tarafından belirlenir. Nginx varsayılan olarak 1 MB, Apache 2 MB, Spring Boot 1 MB ile sınırlar. Büyük dosyalar yüklemek için client_max_body_size (Nginx) veya spring.servlet.multipart.max-file-size (Spring Boot) değerini istenen değere (örneğin, 100 MB) yapılandırın.
Evet, multipart/form-data tek bir istekte birden çok dosyayı destekler. Her dosya, kendi Content-Disposition ve Content-Type'ı ile ayrı bir parça olarak iletilir. HTML formları, input type="file" için multiple özniteliğini kullanır. OkHttp'de her dosya için addFormDataPart çağrılır, Alamofire'da her dosya için append çağrılır.
Boundary, bileşik bir isteğin parçalarını ayıran ve sunucunun bir parçanın nerede bittiğini ve diğerinin nerede başladığını belirlemesini sağlayan benzersiz bir dizedir. İstemci tarafından oluşturulur ve Content-Type başlığında belirtilir. Boundary olmadan, sunucu çok bileşenli bir isteği ayrı alanlara ve dosyalara ayrıştıramaz.
Dosya uzantısına veya istekteki Content-Type'a güvenmeyin — bir saldırgan bunları taklit edebilir. MIME türünü sihirli baytlar (dosyanın ilk baytları) aracılığıyla kontrol edin: Java'da Apache Tika, C/C++'ta libmagic, Linux'ta file komutu veya çerçevenin yerleşik araçları — Java'da Files.probeContentType(), Python'da mimetypes.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun