Dosyayı dahili olarak nasıl gönderir?
Format şu multipart/form-data
şekilde sorulur: enctype = 'multipart / form-data' ne anlama geliyor?
Ş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 .html
dosyaya 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ωb
nedeniyle ω
olduğunu U+03C9
bayt olan, 61 CF 89 62
UTF-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, nc
BSD 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ωb
UTF-8'de) kelimenin tam anlamıyla gönderilir. Sen ile doğrulamak olabilir nc -l localhost 8000 | hd
bayt olduğunu öne sürdüğü:
61 CF 89 62
gönderildi ( 61
== 'a' ve 62
== 'b').
Bu nedenle açıktır:
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
içerik türünü ayarlar ve multipart/form-data
alanların verilen boundary
dize ile ayrıldığını belirtir .
Ancak şunu unutmayın:
boundary=---------------------------735323031399963166993862150
--
gerçek engelden daha az iki baba 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
, filename
verilerin 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 enctype
iç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 a
ve b
benzeri olmayan basılabilir olanlar ise, tek bayt gönderildi 0xCF
ve 0x89
aldı 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 baytta 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.