Yanıtlar:
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-datatext/plainEkleme 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:
text/plain.İstemci tarafı kodu yazarken:
multipart/form-dataformunuzda herhangi bir <input type="file">öğe olduğunda kullanınmultipart/form-dataveya application/x-www-form-urlencodedancak application/x-www-form-urlencodeddaha verimli olacakSunucu tarafı kodu yazarken:
Ç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).
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:
Orada üç olasılık için enctype:
application/x-www-form-urlencodedmultipart/form-data(spesifikasyon RFC7578'i gösterir )text/plain. Bu "bilgisayar tarafından güvenilir bir şekilde yorumlanamaz", bu yüzden asla üretimde kullanılmamalıdır ve daha fazla araştırmayacağız.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:
nc -lveya bir ECHO sunucusu: GET / POST isteklerini kabul eden HTTP test sunucusuFormu 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ω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ω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.
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?
Ş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!
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.
%CFuzun 3 bayt: %, Cve Finsan okunabilir yapma :-) Öyküsü.
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.
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/…
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 .
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.
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.)
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.
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.Ö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.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.
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.
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.
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.
<head>ve <body>alakasız ve kafa karıştırıcı.
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
multipart/form-data. Aynı zamanda oldukça belirsiz; "Hiçbir karakter kodlanmamış" cümlesi ne anlama geliyor? -1.