यह फ़ाइल को आंतरिक रूप से कैसे भेजता है?
प्रारूप को कहा जाता है multipart/form-data
, जैसा कि पूछा गया: enctype = 'multipart / form-data' का क्या अर्थ है?
मैं जा रहा हूँ:
- कुछ और HTML5 संदर्भ जोड़ें
- समझाएं कि वह फॉर्म सबमिट उदाहरण के साथ सही क्यों है
HTML5 संदर्भ
इसके लिए तीन संभावनाएँ हैं enctype
:
उदाहरण कैसे प्रस्तुत करें
एक बार जब आप प्रत्येक विधि का एक उदाहरण देखते हैं, तो यह स्पष्ट हो जाता है कि वे कैसे काम करते हैं, और जब आपको प्रत्येक का उपयोग करना चाहिए।
आप उदाहरणों का उपयोग कर उत्पादन कर सकते हैं:
फॉर्म को एक न्यूनतम .html
फ़ाइल में सहेजें :
<!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>
हम करने के लिए डिफ़ॉल्ट पाठ मान सेट aωb
है, जो साधन aωb
क्योंकि ω
है U+03C9
, जो बाइट्स हैं 61 CF 89 62
UTF-8 में।
अपलोड करने के लिए फ़ाइलें बनाएँ:
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
हमारे छोटे इको सर्वर को चलाएं:
while true; do printf '' | nc -l 8000 localhost; done
अपने ब्राउज़र पर HTML खोलें, फ़ाइलों का चयन करें और सबमिट पर क्लिक करें और टर्मिनल की जांच करें।
nc
प्राप्त अनुरोध को प्रिंट करता है।
पर परीक्षण किया गया: Ubuntu 14.04.3, nc
BSD 1.105, Firefox 40।
बहुखण्डीय / फार्म-डेटा
फ़ायरफ़ॉक्स भेजा:
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--
बाइनरी फ़ाइल और टेक्स्ट फ़ील्ड के लिए, बाइट्स 61 CF 89 62
( aωb
UTF-8 में) शाब्दिक रूप से भेजे जाते हैं। आप इसे सत्यापित कर सकते हैं nc -l localhost 8000 | hd
, जो कहता है कि बाइट्स:
61 CF 89 62
भेजे गए ( 61
== 'a' और 62
== 'b')।
इसलिए यह स्पष्ट है कि:
Content-Type: multipart/form-data; boundary=---------------------------735323031399963166993862150
सामग्री प्रकार सेट करता है multipart/form-data
और कहता है कि फ़ील्ड दिए गए boundary
स्ट्रिंग द्वारा अलग किए गए हैं ।
लेकिन ध्यान दें:
boundary=---------------------------735323031399963166993862150
--
वास्तविक अवरोध की तुलना में दो कम डैड्स हैं
-----------------------------735323031399963166993862150
ऐसा इसलिए है क्योंकि मानक को दो डैश के साथ शुरू करने के लिए सीमा की आवश्यकता होती है --
। अन्य डैश प्रतीत होता है कि फ़ायरफ़ॉक्स ने मनमानी सीमा को लागू करने के लिए कैसे चुना। RFC 7578 में स्पष्ट रूप से उल्लेख किया गया है कि उन दो प्रमुख डैश --
की आवश्यकता है:
4.1। मल्टीपार्ट / फॉर्म-डेटा का "सीमा" पैरामीटर
अन्य मल्टीपार्ट प्रकारों के साथ, भागों को सीमारेखा, "-", और "सीमा" पैरामीटर के मान से निर्मित सीमा परिसीमन के साथ सीमांकित किया जाता है।
हर क्षेत्र को अपने डेटा से पहले कुछ उप शीर्षलेख मिलते हैं: Content-Disposition: form-data;
क्षेत्र name
, filename
डेटा के बाद।
सर्वर अगली सीमा स्ट्रिंग तक डेटा पढ़ता है। ब्राउज़र को एक सीमा चुननी चाहिए जो किसी भी क्षेत्र में दिखाई नहीं देगी, इसलिए यही कारण है कि सीमा अनुरोधों के बीच भिन्न हो सकती है।
क्योंकि हमारे पास अद्वितीय सीमा है, डेटा का कोई एन्कोडिंग आवश्यक नहीं है: बाइनरी डेटा को भेजा जाता है।
TODO: इष्टतम सीमा आकार ( log(N)
I bet) क्या है, और इसे खोजने वाले एल्गोरिथम का नाम / रनिंग टाइम क्या है? यहां से पूछा गया: /cs/39687/find-the-shortest-fterence-that-is-not-a-sub-fterence-of-a-set-of- आएंगे
Content-Type
ब्राउज़र द्वारा स्वचालित रूप से निर्धारित किया जाता है।
यह कैसे निर्धारित किया जाता है वास्तव में पूछा गया था: ब्राउज़र द्वारा अपलोड की गई फ़ाइल का माइम प्रकार कैसे है?
आवेदन / x-www फार्म-urlencoded
अब बदलने enctype
के लिए application/x-www-form-urlencoded
, ब्राउज़र, और पुनः सबमिट लोड करें।
फ़ायरफ़ॉक्स भेजा:
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
और b
एक बाइट में भेजा गया है, जबकि तरह प्रिंट न हो सकने वाले 0xCF
और 0x89
ले लिया 3 बाइट्स प्रत्येक: %CF%89
!
तुलना
फ़ाइल अपलोड में अक्सर गैर-मुद्रण योग्य वर्ण (जैसे चित्र) होते हैं, जबकि टेक्स्ट फ़ॉर्म लगभग कभी नहीं होते हैं।
उदाहरणों से हमने देखा है कि:
multipart/form-data
: संदेश में सीमा उपरि के कुछ बाइट्स जोड़ता है, और इसकी गणना करने में कुछ समय बिताना चाहिए, लेकिन प्रत्येक बाइट को एक बाइट में भेजता है।
application/x-www-form-urlencoded
: प्रति फ़ील्ड एक एकल बाइट सीमा है ( &
), लेकिन प्रत्येक गैर-मुद्रण योग्य वर्ण के लिए 3x का एक रैखिक ओवरहेड कारक जोड़ता है ।
इसलिए, भले ही हम फ़ाइलों को भेज सकें application/x-www-form-urlencoded
, हम नहीं चाहेंगे, क्योंकि यह इतना अक्षम है।
लेकिन टेक्स्ट फ़ील्ड में पाए जाने वाले मुद्रण योग्य वर्णों के लिए, इससे कोई फर्क नहीं पड़ता है और कम ओवरहेड उत्पन्न करता है, इसलिए हम इसका उपयोग करते हैं।