Enctype = 'multipart / form-data' ne anlama geliyor?


Yanıtlar:


1570

Bir POST isteği yaptığınızda, isteğin gövdesini oluşturan verileri bir şekilde kodlamanız gerekir.

HTML formları üç kodlama yöntemi sağlar.

  • application/x-www-form-urlencoded (varsayılan)
  • multipart/form-data
  • text/plain

Ekleme konusunda çalışmalar yapılıyordu application/json, ama bu terk edildi.

(HTML form gönderimi dışında başka araçlar kullanılarak oluşturulan HTTP istekleri ile başka kodlamalar da mümkündür. JSON, web hizmetleriyle kullanım için yaygın bir biçimdir ve bazıları hala SOAP kullanır.)

Biçimlerin özellikleri çoğu geliştirici için önemli değildir. Önemli noktalar:

  • Asla kullanmayın text/plain.

İstemci tarafı kodu yazarken:

  • multipart/form-dataformunuzda herhangi bir <input type="file">öğe olduğunda kullanın
  • aksi takdirde kullanabilir multipart/form-dataveya application/x-www-form-urlencodedancak application/x-www-form-urlencodeddaha verimli olacak

Sunucu tarafı kodu yazarken:

  • Önceden yazılmış bir form işleme kitaplığı kullanma

Çoğu (Perl'ler CGI->paramveya PHP'nin $_POSTsüper küresi tarafından maruz kalanlar gibi ) sizin için farklılıklarla ilgilenecektir. Sunucu tarafından alınan ham girdiyi ayrıştırmaya çalışmayın.

Bazen her iki biçimi de işleyemeyen bir kütüphane bulabilirsiniz. Node.js'nin form verilerini işlemek için en popüler kütüphanesi, çok parçalı istekleri işleyemeyen (ancak yapabilen bazı alternatifleri öneren belgelere sahip) gövde ayrıştırıcısıdır .


Ham verileri ayrıştırmak veya oluşturmak için bir kitaplık yazıyorsanız (veya hata ayıklama yapıyorsanız), format hakkında endişelenmeye başlamanız gerekir. Ayrıca, ilgi uğruna bunu bilmek isteyebilirsiniz.

application/x-www-form-urlencoded , URL'nin sonundaki bir sorgu dizesiyle aşağı yukarı aynıdır.

multipart/form-dataönemli ölçüde daha karmaşıktır ancak tüm dosyaların verilere dahil edilmesini sağlar. Sonuç için bir örnek HTML 4 spesifikasyonunda bulunabilir .

text/plainHTML 5 tarafından tanıtıldı ve yalnızca hata ayıklama için kullanışlıdır - spesifikasyondan : Bunlar bilgisayar tarafından güvenilir bir şekilde yorumlanamaz - ve diğerlerinin araçlarla (çoğu tarayıcının geliştirici araçlarındaki Ağ Paneli gibi ) daha iyi olduğunu iddia ediyorum bunun için).


5
@Quentin Affedersiniz, tüm formlar için çok parçalı kullanırsak herhangi bir olası sorun ne olur? dosyaları ile beyazlatır.
Webinan

12
GET formları için bir anlam ifade etmez ve isteklerin dosya boyutunu büyütür.
Quentin

@Quentin çok parçalı form verileri varsayılan olarak akış olarak gönderilir mi?
Growler

Enctype içindeki enc bir şey mi ifade ediyor?
Philip Rego

1
"HTML formları üç ENC oding yöntemi sağlar"
Quentin

449

ne zaman kullanmalıyız

Quentin'in cevabı doğrudur: multipart/form-dataform bir dosya yüklemesi içeriyorsa kullanın , application/x-www-form-urlencodedaksi takdirde atlarsanız varsayılan değerdir enctype.

Şuna gidiyorum:

  • biraz daha HTML5 referansı ekle
  • bir form göndererek neden haklı olduğunu açıklayın

HTML5 referansları

Orada üç olasılık için enctype:

Örnekler nasıl oluşturulur?

Her yöntemin bir örneğini gördüğünüzde, nasıl çalıştıklarını ve her birini ne zaman kullanmanız gerektiği açık hale gelir.

Aşağıdakileri kullanarak örnekler üretebilirsiniz:

Formu minimal bir .htmldosyaya kaydedin :

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <title>upload</title>
</head>
<body>
<form action="http://localhost:8000" method="post" enctype="multipart/form-data">
  <p><input type="text" name="text1" value="text default">
  <p><input type="text" name="text2" value="a&#x03C9;b">
  <p><input type="file" name="file1">
  <p><input type="file" name="file2">
  <p><input type="file" name="file3">
  <p><button type="submit">Submit</button>
</form>
</body>
</html>

Biz varsayılan metin değeri a&#x03C9;b, araçlar aωbnedeniyle ωolduğunu U+03C9bayt olan, 61 CF 89 62UTF-8.

Yüklenecek dosyalar oluşturun:

echo 'Content of a.txt.' > a.txt

echo '<!DOCTYPE html><title>Content of a.html.</title>' > a.html

# Binary file containing 4 bytes: 'a', 1, 2 and 'b'.
printf 'a\xCF\x89b' > binary

Küçük yankı sunucumuzu çalıştırın:

while true; do printf '' | nc -l 8000 localhost; done

Tarayıcınızda HTML'yi açın, dosyaları seçin ve gönder'i tıklayın ve terminali kontrol edin.

nc alınan isteği yazdırır.

Test tarihi: Ubuntu 14.04.3, ncBSD 1.105, Firefox 40.

Çok parçalı / form-

Firefox gönderdi:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
Content-Length: 834

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text1"

text default
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="text2"

aωb
-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

Content of a.txt.

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html

<!DOCTYPE html><title>Content of a.html.</title>

-----------------------------735323031399963166993862150
Content-Disposition: form-data; name="file3"; filename="binary"
Content-Type: application/octet-stream

aωb
-----------------------------735323031399963166993862150--

İkili dosya ve metin alanı için baytlar 61 CF 89 62( aωbUTF-8'de) kelimenin tam anlamıyla gönderilir. Bunu nc -l localhost 8000 | hd, baytların söylediği ile doğrulayabilirsiniz :

61 CF 89 62

gönderildi ( 61== 'a' ve 62== 'b').

Bu nedenle açıktır:

  • Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150içerik türünü ayarlar ve multipart/form-dataalanların verilen boundarydize ile ayrıldığını belirtir .

    Ancak şunu unutmayın:

    boundary=---------------------------735323031399963166993862150

    --asıl engelden daha az iki babası var

    -----------------------------735323031399963166993862150

    Bunun nedeni, standardın sınırın iki tire ile başlamasını gerektirmesidir --. Diğer çizgiler, Firefox'un keyfi sınırı nasıl uyguladığını gösteriyor. RFC 7578, bu iki önde gelen tirenin --gerekli olduğunu açıkça belirtmektedir :

    4.1. "Sınır" Çok parçalı / form verisi parametresi

    Diğer çok parçalı tiplerde olduğu gibi, parçalar da CRLF, "-" ve "sınır" parametresinin değeri kullanılarak oluşturulan bir sınır sınırlayıcı ile sınırlandırılır.

  • Her alan kendi verilerine önce bazı alt başlıklarını alır: Content-Disposition: form-data;, alan name, filenameverilerin ardından.

    Sunucu, verileri bir sonraki sınır dizesine kadar okur. Tarayıcı, alanların hiçbirinde görünmeyecek bir sınır seçmelidir, bu nedenle sınır istekler arasında değişebilir.

    Benzersiz sınırımız olduğu için, verilerin kodlanması gerekmez: ikili veriler olduğu gibi gönderilir.

    YAPILACAKLAR: İdeal sınır boyutu ( log(N)bahse girerim) ve onu bulan algoritmanın adı / çalışma süresi nedir? Sorulduğu yer: /cs/39687/find-the-shortest-sequence-that-is-not-a-sub-sequence-of-a-set-of-sequences

  • Content-Type tarayıcı tarafından otomatik olarak belirlenir.

    Tam olarak nasıl belirlendi: Şu şekilde yüklenen bir dosyanın mime türü tarayıcı tarafından nasıl belirlenir?

Uygulama / x-www-form-urlencoded

Şimdi değiştirmek enctypeiçin application/x-www-form-urlencoded, tarayıcı ve yeniden gönderin yükleyin.

Firefox gönderdi:

POST / HTTP/1.1
[[ Less interesting headers ... ]]
Content-Type: application/x-www-form-urlencoded
Content-Length: 51

text1=text+default&text2=a%CF%89b&file1=a.txt&file2=a.html&file3=binary

Açıkça, dosya verileri gönderilmedi, sadece temel isimler. Yani bu dosyalar için kullanılamaz.

Metin alanına gelince, biz gibi o zamanki yazdırılabilir karakterleri görmek ave bbenzeri olmayan basılabilir olanlar ise, tek bayt gönderildi 0xCFve 0x89aldı 3 bayt her: %CF%89!

karşılaştırma

Dosya yüklemeleri genellikle yazdırılamayan çok sayıda karakter (örn. Resimler) içerirken metin formları neredeyse hiç yapmaz.

Örneklerden şunu gördük:

  • multipart/form-data: mesaja birkaç bayt sınır ek yükü ekler ve bunu hesaplamak için biraz zaman harcamalıdır, ancak her baytı bir bayt olarak gönderir.

  • application/x-www-form-urlencoded: alan başına tek bir bayt sınırına ( &) sahiptir, ancak yazdırılamayan her karakter için 3x doğrusal bir ek yük faktörü ekler .

Bu nedenle, ile dosya gönderebilsek bile application/x-www-form-urlencoded, istemezdik, çünkü bu çok verimsiz.

Ancak metin alanlarında bulunan yazdırılabilir karakterler için önemli değildir ve daha az ek yük oluşturur, bu yüzden sadece kullanırız.


3
Khanna111 @ %CFuzun 3 bayt: %, Cve Finsan okunabilir yapma :-) Öyküsü.
Ciro Santilli 法轮功 病毒 审查 六四 事件 法轮功

6
OS X'te, nchem ve -lhem de -pbağımsız değişkenleri aynı anda kabul etmez . Ama bu benim için çalışıyor: while true; do printf '' | nc -l 8000; done.
PhilipS

4
Bahsedilmeyen küçük ama önemli bir nokta Content-Type, iki kısa çizginin ( --) daha az olması, yani mesaj gövdesinde aslında sınırı kullanırken, önek eklemeniz gerektiğidir --. Ayrıca, son sınırın --eklenmesi gerekir , ancak bunu fark etmek yeterince kolaydır. Bkz. Stackoverflow.com/questions/3508252/…
Bernard

1
Söyleyebildiğim kadarıyla, HERHANGİ BİR GÖSTERGEYİ sınırda koymanın amacı, talebin sözdizimini gözle kontrol etmeyi imkansız hale getirmektir. Lütfen bunları sınır simgelerinizde kullanmayın.
Dewi Morgan

1
@DewiMorgan Tamamen haklısın. Gönderiyi düzenledim ve çizgiyi sınır dizesinden kaldırdım.
Maksimum

91

enctype='multipart/form-datadosyaların bir POST yoluyla gönderilmesine izin veren bir kodlama türüdür . Oldukça basit, bu kodlama olmadan dosyalar POST yoluyla gönderilemez .

Kullanıcının form aracılığıyla dosya yüklemesine izin vermek istiyorsanız, bu şifreyi kullanmanız gerekir .


Yani .. dosya ikili bir dosya değilse, bu olmadan çalışabilir miyiz?
Yugal Jindle

Anladığım kadarıyla, multipart/form-dataikili olmayan dosyaları göndermek için kullanabilirsiniz , ancak verimsizdir. Kullanmanın application/x-www-form-urlencodedikili olmayan veri göndermenin doğru yolu olduğuna inanıyorum , ancak ikili olmayan dosyalarla daha fazla deneyime sahip birisinin beni düzeltmesi gerekebilir.
Matt Asbury

11
multipart/form-dataBir dosyayı göndermek için kullanmanın ana avantajı, dosyanın hem ön uçta hem de arka uçta otomatik olarak çalışmasıdır. Özel bir işlem yapmanız gerekmez. Tüm dosyalar, yalnızca metin içermeleri gerekse bile ikilidir. application/x-www-form-urlencodedekli dosyaları olmayan bir formu POST etmenin standart yoludur. multipart/form-dataekli dosya (lar) içeren bir formu POST ETMENİN standart yoludur. ( Sunucu ve istemci arasındaki iletişimde yaygın olan application/jsonve gibi çok sayıda başka kodlama da vardır application/json-patch+json.)
Daniel Luna

6
Tabii ki resminizi base64 kodlayabilir ve düz dize verileri olarak gönderebilirsiniz.
James

3
Yukarıdaki @ Prospero'nun yorumuna ek olarak: kesinlikle dosyaları kullanmadan POST yoluyla gönderebilirsiniz multipart/form-data. Yapamayacağınız şey , JavaScript olmadan sıradan bir HTML formu gönderimi kullanmaktır. Kullanılacak bir form ayarlamak multipart/form-data, HTML'nin JavaScript kullanmadan POST dosyalarına izin vermesini sağlayan tek mekanizmadır . Bunun cevapta yeterince açık olmadığını ve saf bir okuyucunun dosya olmadan gönderilememesinin HTTP'ninmultipart/form-data bir sınırlaması olduğunu düşünebileceğini hissediyorum ; konu bu değil.
Mark Amery

81

Bir form gönderirken, tarayıcınıza HTTP protokolü üzerinden, bir TCP / IP protokolü mesaj yapısında düzgün bir şekilde zarflanmış bir mesaj göndermesini söylersiniz. Bir HTML sayfasının sunucuya veri göndermenin bir yolu vardır: <form>s kullanarak .

Bir form gönderildiğinde, bir HTTP İsteği oluşturulur ve sunucuya gönderilir; ileti, formdaki alan adlarını ve kullanıcı tarafından doldurulan değerleri içerir. Bu iletim POSTveya GET HTTP yöntemleriyle olabilir .

  • POST tarayıcınıza bir HTTP mesajı oluşturmasını ve tüm içeriği mesajın gövdesine koymasını söyler (bir şeyler yapmanın çok yararlı bir yolu, daha güvenli ve aynı zamanda esnek).
  • GETform verilerini sorgu dizesinde gönderir . Veri gösterimi ve uzunluğu ile ilgili bazı kısıtlamaları vardır.

Formunuzu sunucuya nasıl göndereceğinizi belirtme

Özniteliğin enctypeyalnızca POSTyöntemi kullanırken bir anlamı vardır . Belirtildiğinde, tarayıcıya formu içeriğini belirli bir şekilde kodlayarak göndermesi talimatını verir. Gönderen MDN'yi - Form enctype :

Method özniteliğinin değeri post olduğunda, enctype, formu sunucuya göndermek için kullanılan MIME içerik türüdür.

  • application/x-www-form-urlencoded: Bu varsayılan ayardır. Form gönderildiğinde, tüm adlar ve değerler toplanır ve URL Kodlaması son dizgide gerçekleştirilir.
  • multipart/form-data: Karakterler kodlanmamış. Formda dosya yükleme denetimi varsa bu önemlidir. İkili dosyayı göndermek istiyorsunuz ve bu da bit akımının değiştirilmemesini sağlıyor.
  • text/plain: Boşluklar dönüştürülür, ancak başka kodlama yapılmaz.

Güvenlik

Formları gönderirken, RFC 7578 Bölüm 7: Çok parçalı form verileri - Güvenlikle ilgili konular :

Tüm form işleme yazılımları
, genellikle gizli veya kişisel olarak
tanımlayıcı bilgiler içerdiğinden, kullanıcı tarafından sağlanan form verilerini hassas bir şekilde ele almalıdır . Web tarayıcılarında form "otomatik doldurma" özelliklerinin yaygın kullanımı vardır; bunlar, kullanıcıları
aksi takdirde
zararsız görevleri tamamlarken bilmeden gizli bilgiler göndermeleri için kandırmak için kullanılabilir . çok parçalı / form verileri,
bütünlüğü denetlemek, gizliliği sağlamak, kullanıcı
karışıklığını veya diğer güvenlik özelliklerini önlemek için herhangi bir özellik sağlamaz ; bu endişeler
, form doldurma ve form-veri yorumlama uygulamaları tarafından ele alınmalıdır .

Formları alan ve işleyen başvurular, gönderilmesi amaçlanmayan talep eden form işleme sitesine geri veri vermemeye dikkat etmelidir.

Content-
Disposition üstbilgisi alanının dosya adını ,
alıcının dosya alanındaki dosyaların üzerine yanlışlıkla yazmamak için yorumlarken önemlidir .

Bir geliştiriciyseniz ve sunucunuz kullanıcılar tarafından gönderilen ve hassas bilgiler içerebilecek formları işleyecekse bu sizi ilgilendirir.


1
En son düzenlemeden sonra güvenlikle ilgili şeyler, ne yaptıkları sorusuyla ilgisizdir enctype. Kelimenin tam anlamıyla RFC'den olduğunu biliyorum multipart/form-data, ancak yine de verinin application/x-www-form-urlencodedveya olarak gönderilip gönderilmeyeceğine tamamen dik olan formların gönderilmesi ile ilgili keyfi bir güvenlik kayması multipart/form-data.
Mark Amery

38

enctype='multipart/form-data'hiçbir karakterin kodlanmayacağı anlamına gelir. bu yüzden sunucuya dosya yüklerken bu tür kullanılır.
Dolayısıyla multipart/form-data, bir form bir dosyanın içeriği gibi ikili veriler yüklenmesini gerektirdiğinde kullanılır


8

Dosya içeriği form kullanılarak bir URL parametresinin içine yerleştirilemediğinden, yöntem niteliğini POST olarak ayarlayın.

Her bir dosya için bir tane ve onlarla gönderilebilecek form gövdesi metni için bir tane olmak üzere birden çok parçaya ayrılacağından, enctype değerini multipart / form-data olarak ayarlayın.


Bu, POSTbir form aracılığıyla bir dosya göndermek için yeterli olması ve eklemenin multipart/form-databelli belirsiz bir şekilde bir bonus olduğu anlamına gelir . Konu bu değil. Çoğu dosya kesinlikle kullanılmasını gerektirir multipart/form-data.
underscore_d

1
  • enctype ( ENC ode TYPE ) özelliği, form verilerinin sunucuya gönderilirken nasıl kodlanması gerektiğini belirtir.
  • multipart / form-data , dosya yüklemesi olan form öğesinde kullanılan enctype özniteliğinin değerlerinden biridir. çok parçalı form verilerinin birden çok parçaya bölündüğü ve sunucuya gönderileceği anlamına gelir .

5
Enctype'in şifreleme türü için geçerli olmadığını düşünüyorum . Bu düzeyde herhangi bir şifreleme yoktur. Tahminim ya kodlama tipi ya da kapalı tip. Ama kesinlikle şifreleme türü değil.
Yeo

1
Son merminiz burada ilgili <head>ve <body>alakasız ve kafa karıştırıcı.
Mark Amery

0

Genellikle bu, bir dosya yüklemesini veri olarak alması gereken bir POST formunuz olduğunda ... bu, sunucuya aktarılan verileri nasıl kodlayacağını söyler, bu durumda kodlanmayacaktır çünkü sadece aktarır ve yükler dosyaları sunucuya, örneğin bir resim veya pdf yüklerken


-3

Enctype özniteliği, form verilerinin sunucuya gönderilirken nasıl kodlanması gerektiğini belirtir.

Enctype özniteliği yalnızca method = "post" olduğunda kullanılabilir.

Hiçbir karakter kodlanmamış. Dosya yükleme denetimi olan formları kullanırken bu değer gereklidir

Gönderen W3Schools'da


2
Bu alıntıdan bahsetmiyor bile multipart/form-data. Aynı zamanda oldukça belirsiz; "Hiçbir karakter kodlanmamış" cümlesi ne anlama geliyor? -1.
Mark Amery
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.