Ben multipart/form-data
hakkında bir soru sormak istiyorum. HTTP başlığında Content-Type: multipart/form-data; boundary=???
olduğunu görüyorum.
Kullanıcı tarafından tanımlanması serbest midir? Yoksa HTML'den mi üretiliyor? Benim ???'yi tanımlamam mümkün mü? = abcdefg
?
???
kullanıcı tarafından tanımlanmakta serbest mi?
Evet.
yoksa HTML tarafından mı sağlanıyor?
Hayır. HTML'nin bununla hiç bir ilgisi yoktur. Aşağıdan okuyun.
???
'yiabcdefg
olarak tanımlamam mümkün mü?
Evet.
Aşağıdaki verileri web sunucusuna göndermek istiyorsanız:
name = John
age = 12
application/x-www-form-urlencoded` kullanarak bu şekilde olacaktır:
name=John&age=12
Gördüğünüz gibi, sunucu parametrelerin bir ve işareti &
ile ayrıldığını biliyor. Bir parametre değeri için &
gerekiyorsa, kodlanmalıdır.
Peki sunucu multipart/form-data
kullanan bir HTTP isteği aldığında bir parametre değerinin nerede başlayıp nerede bittiğini nasıl bilir?
sınırını* kullanarak, &
'a benzer.
Örneğin:
--XXX
Content-Disposition: form-data; name="name"
John
--XXX
Content-Disposition: form-data; name="age"
12
--XXX--
Bu durumda sınır değeri XXX
olur. Bunu Content-Type
başlığında belirtirsiniz, böylece sunucu aldığı veriyi nasıl böleceğini bilir.
Yani yapman gereken:
Sunucuya gönderilen HTTP verilerinde görünmeyecek bir değer kullanın.
Tutarlı olun ve talep mesajının her yerinde aynı değeri kullanın.
Sorunun tam cevabı şudur: Evet, uzunluğu 70 baytı geçmediği ve yalnızca 7-bit US-ASCII
(yazdırılabilir) karakterlerden oluştuğu sürece boundary
parametresi için rastgele bir değer kullanabilirsiniz.
Eğer multipart/*
içerik türlerinden birini kullanıyorsanız, aslında Content-Type
başlığında boundary
parametresini belirtmeniz gereklidir, aksi takdirde sunucu (HTTP isteği durumunda) yükü ayrıştıramayacaktır.
Yük verilerinde yalnızca US-ASCII
karakter kümesinin kullanılacağından kesinlikle emin değilseniz, Content-Type
başlığınızda charset
parametresini UTF-8
olarak ayarlamak isteyebilirsiniz.
RFC2046]'dan ilgili birkaç alıntı:
4.1.2. Charset Parametresi:
Diğer bazı parametre değerlerinin aksine, charset parametresinin değerleri büyük/küçük harfe duyarlı DEĞİLDİR. Bir charset parametresi olmadığında varsayılması gereken varsayılan karakter kümesi US-ASCII'dir.
5.1. Çok Parçalı Ortam Türü
Content-Transfer-Encoding alanının [RFC 2045] tanımında belirtildiği gibi, "multipart" türündeki varlıklar için "7bit", "8bit" veya "binary" dışında hiçbir kodlamaya izin verilmez. Çok parçalı" sınır sınırlayıcıları ve başlık alanları her durumda 7bit US-ASCII olarak temsil edilir (başlık alanları RFC 2047 uyarınca US-ASCII olmayan başlık metnini kodlayabilir) ve gövde parçaları içindeki veriler, her uygun gövde parçası için Content-Transfer-Encoding alanları ile parça bazında kodlanabilir.
Çok parçalı varlıklar için Content-Type alanı bir parametre gerektirir, "boundary". Sınır sınırlayıcı satırı daha sonra tamamen iki tire karakterinden ("-", ondalık değer 45) oluşan bir satır olarak tanımlanır ve ardından Content-Type başlık alanındaki sınır parametresi değeri, isteğe bağlı doğrusal boşluk ve sonlandırıcı bir CRLF gelir.
Sınırlayıcılar kapsüllenmiş materyal içinde görünmemeli ve baştaki iki tire hariç 70 karakterden uzun olmamalıdır.
Son gövde parçasını takip eden sınırlayıcı çizgi, başka gövde parçalarının takip etmeyeceğini gösteren ayırt edici bir sınırlayıcıdır. Böyle bir sınırlayıcı satır, sınır parametre değerinden sonra iki tire daha eklenerek önceki sınırlayıcı satırlarla aynıdır.
İşte rastgele bir sınır kullanan bir örnek:
Content-Type: multipart/form-data; charset=utf-8; boundary="another cool boundary"
--another cool boundary
Content-Disposition: form-data; name="foo"
bar
--another cool boundary
Content-Disposition: form-data; name="baz"
quux
--another cool boundary--
"Çok Amaçlı İnternet Posta Uzantıları (MIME) Bölüm İki: Medya Türleri"
multipart/form-data, ad/değer çiftlerini ayırmak için boundary içerir. Sınır, bir form gönderildiğinde aktarılan her bir ad/değer çifti yığınının işaretleyicisi gibi davranır. Sınır otomatik olarak bir istek başlığının içerik türüne eklenir.
enctype="multipart/form-data"* özniteliğine sahip form, Content-Type : multipart/form-data; boundary --- WebKit193844043-h (browser generated vaue*) istek başlığına sahip olacaktır.
Aktarılan yük şuna benzer:
Content-Type: multipart/form-data; boundary=---WebKitFormBoundary7MA4YWxkTrZu0gW
-----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”file”; filename=”captcha”
Content-Type:
-----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name=”action”
submit
-----WebKitFormBoundary7MA4YWxkTrZu0gW--
Webservice tarafında, @Consumes("multipart/form-data") formunda tüketilir.
Dikkat, web hizmetinizi chrome postman kullanarak test ederken, ek göndermek için form verileri seçeneğini (radyo düğmesi) ve açılır kutudan Dosya menüsünü işaretlemeniz gerekir. Content-type'ın multipart/form-data olarak açık bir şekilde sağlanması hata verir. Çünkü sınır eksiktir, çünkü post man'ın curl isteğini, iyi çalışan sınırı ekleyerek içerik türü ile sunucuya geçersiz kılar.