application/x-www-form-urlencoded veya multipart/form-data?

HTTP'de verileri POST etmenin iki yolu vardır: application/x-www-form-urlencoded ve multipart/form-data. Çoğu tarayıcının yalnızca multipart/form-data kullanıldığında dosya yükleyebildiğini anlıyorum. API bağlamında kodlama türlerinden birinin ne zaman kullanılacağına dair ek bir kılavuz var mı (tarayıcı dahil değil)? Bu örneğin aşağıdakilere dayalı olabilir:

  • veri boyutu
  • ASCII olmayan karakterlerin varlığı
  • (kodlanmamış) ikili veriler üzerinde varlık
  • ek veri aktarma ihtiyacı (dosya adı gibi)

Şu ana kadar web üzerinde farklı içerik türlerinin kullanımına ilişkin resmi bir kılavuz bulamadım.

Çözüm

TL;DR

Özet; iletilecek ikili (alfanümerik olmayan) verileriniz (veya önemli boyutta bir yükünüz) varsa, multipart/form-data kullanın. Aksi takdirde, application/x-www-form-urlencoded kullanın.


Bahsettiğiniz MIME türleri, HTTP POST istekleri için kullanıcı aracılarının (tarayıcılar) desteklemesi gereken iki Content-Type başlığıdır. Bu tür isteklerin her ikisinin de amacı sunucuya bir isim/değer çifti listesi göndermektir. İletilen verinin türüne ve miktarına bağlı olarak, yöntemlerden biri diğerinden daha verimli olacaktır. Bunun nedenini anlamak için, her birinin gizli olarak ne yaptığına bakmanız gerekir.

Application/x-www-form-urlencodediçin, sunucuya gönderilen HTTP mesajının gövdesi aslında dev bir sorgu dizesidir -- isim/değer çiftleri ve işareti (&) ile ayrılır ve isimler değerlerden eşittir sembolü (=`) ile ayrılır. Bunun bir örneği şöyledir: 

MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

Spesifikasyon]'a göre (http://www.w3.org/TR/html401/interact/forms.html):

[Rezerve ve] alfanümerik olmayan karakterlerin yerine `%HH', bir yüzde işareti ve karakterin ASCII kodunu temsil eden iki onaltılık basamak kullanılır

Bu, değerlerimizden birinde bulunan alfanümerik olmayan her bayt için, onu temsil etmek için üç bayt alacağı anlamına gelir. Büyük ikili dosyalar için, yükü üçe katlamak oldukça verimsiz olacaktır.

İşte bu noktada multipart/form-data devreye girer. İsim/değer çiftlerini iletmek için kullanılan bu yöntemde, her çift bir MIME mesajında (diğer cevaplarda açıklandığı gibi) bir "part" olarak temsil edilir. Parçalar belirli bir dize sınırı ile ayrılır (özellikle bu sınır dizesi "value" yüklerinin hiçbirinde yer almayacak şekilde seçilir). Her parçanın Content-Type ve özellikle Content-Disposition gibi kendi MIME başlık kümesi vardır, bu da her parçaya "adını verebilir." Her isim/değer çiftinin değer parçası, MIME mesajının her bir parçasının yüküdür. MIME spesifikasyonu, değer yükünü temsil ederken bize daha fazla seçenek sunar - bant genişliğinden tasarruf etmek için ikili verilerin daha verimli bir kodlamasını seçebiliriz (örneğin, taban 64 veya hatta ham ikili).

Neden her zaman multipart/form-data kullanılmıyor? Kısa alfanümerik değerler için (çoğu web formu gibi), tüm MIME başlıklarını eklemenin ek yükü, daha verimli ikili kodlamadan elde edilecek herhangi bir tasarruftan önemli ölçüde ağır basacaktır.

Yorumlar (16)

HTTP'nin çok parçalı veya x-www-form-urlencoded POST ile sınırlı olduğunu sanmıyorum. Content-Type Header][1] HTTP POST yöntemine ortogonaldir (size uygun olan MIME türünü doldurabilirsiniz). Bu aynı zamanda tipik HTML gösterimi tabanlı web uygulamaları için de geçerlidir (örneğin, json yükü ajax istekleri için yük iletmek için çok popüler oldu).

HTTP üzerinden Restful API ile ilgili olarak karşılaştığım en popüler içerik türleri application/xml ve application/json.

application/xml:

  • veri boyutu: XML çok ayrıntılıdır, ancak sıkıştırma kullanıldığında ve yazma erişimi durumunun (örneğin POST veya PUT yoluyla) okuma erişiminden çok daha nadir olduğu düşünüldüğünde genellikle bir sorun değildir (çoğu durumda tüm trafiğin
Yorumlar (3)

Manuel'in söylediği pek çok şeye katılıyorum. Aslında, yorumları bu url'ye atıfta bulunuyor...

http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4

... ki bu da şöyle diyor:

İçerik türü "application/x-www-form-urlencoded" olduğunu büyük gönderiler için verimsiz ikili veri veya metin miktarları ASCII olmayan karakterler içerir. Bu içerik türü "multipart/form-data" form göndermek için kullanılmalıdır dosyaları, ASCII olmayan verileri içeren, ve ikili veriler.

Ancak, benim için araç/çerçeve desteğine bağlı.

  • Hangi araçları ve çerçeveleri kullanıyorsunuz? API kullanıcılarınızın inşa etmesini bekleyin uygulamalarını nasıl kullanıyorlar?
  • Onlar var mı kullanabilecekleri çerçeveler veya bileşenler bir yöntemi diğerine tercih eden Başka?

Kullanıcılarınız ve API'nizi nasıl kullanacakları hakkında net bir fikir edinirseniz, bu karar vermenize yardımcı olacaktır. API kullanıcılarınız için dosya yüklemeyi zorlaştırırsanız, onları desteklemek için çok fazla zaman harcayacağınızdan uzaklaşacaklardır.

Buna ikincil olarak, API'nizi yazmak için sahip olduğunuz araç desteği ve bir yükleme mekanizmasını diğerine göre barındırmanın sizin için ne kadar kolay olduğu gelecektir.

Yorumlar (2)