http - आवेदन/एक्स-www-form-urlencoded या multipart/form-data?




post http-headers (4)

HTTP में डेटा पोस्ट करने के दो तरीके हैं: application/x-www-form-urlencoded और multipart/form-data । मैं समझता हूं कि अधिकांश ब्राउज़र केवल multipart/form-data का उपयोग होने पर फ़ाइलों को अपलोड करने में सक्षम होते हैं। क्या एपीआई संदर्भ में एन्कोडिंग प्रकारों में से किसी एक का उपयोग करने के लिए कोई अतिरिक्त मार्गदर्शन है (कोई ब्राउज़र शामिल नहीं है)? यह उदाहरण के आधार पर हो सकता है:

  • डेटा आकार
  • गैर-ASCII वर्णों का अस्तित्व
  • बाइनरी डेटा (unencoded) पर अस्तित्व
  • अतिरिक्त डेटा स्थानांतरित करने की आवश्यकता (जैसे फ़ाइल नाम)

मुझे मूल रूप से विभिन्न सामग्री-प्रकारों के उपयोग के संबंध में वेब पर कोई औपचारिक मार्गदर्शन नहीं मिला।


एचटीएमएल 5 कैनवास छवि डेटा अपलोड करने के लिए मेरी तरफ से थोड़ा सा संकेत:

मैं प्रिंट-शॉप के लिए एक प्रोजेक्ट पर काम कर रहा हूं और एचटीएमएल 5 canvas तत्व से आने वाले सर्वर पर छवियों को अपलोड करने के कारण कुछ समस्याएं थीं। मैं कम से कम एक घंटे तक संघर्ष कर रहा था और मुझे अपने सर्वर पर छवि को सही ढंग से सहेजने के लिए नहीं मिला।

एक बार जब मैं सामग्री को सेट करता contentType मेरे jQuery AJAX कॉल के application/x-www-form-urlencoded को सही तरीके से चला गया और बेस 64-एन्कोडेड डेटा का सही ढंग से व्याख्या किया गया और एक छवि के रूप में सफलतापूर्वक सहेजा गया।

शायद यह किसी की मदद करता है!


मुझे नहीं लगता कि HTTP मल्टीपार्ट या एक्स-www-form-urlencoded में POST तक सीमित है। सामग्री-प्रकार शीर्षलेख HTTP पोस्ट विधि के लिए ऑर्थोगोनल है (आप एमआईएमई प्रकार को भर सकते हैं जो आपको उपयुक्त बनाता है)। यह सामान्य HTML प्रतिनिधित्व आधारित वेबपैस के मामले में भी है (उदाहरण के लिए जेसन पेलोड AJAX अनुरोधों के लिए पेलोड ट्रांसमिट करने के लिए बहुत लोकप्रिय हो गया है)।

HTTP पर रीस्टफुल एपीआई के बारे में सबसे लोकप्रिय सामग्री-प्रकार जिनके साथ मैं संपर्क में आया था वे एप्लिकेशन / एक्सएमएल और एप्लिकेशन / जेसन हैं।

application / xml:

  • डेटा आकार: एक्सएमएल बहुत वर्बोज़, लेकिन आमतौर पर संपीड़न का उपयोग करते समय कोई समस्या नहीं होती है और सोचती है कि लेखन पहुंच केस (जैसे POST या PUT के माध्यम से) पढ़ने-पहुंच के रूप में बहुत दुर्लभ है (कई मामलों में यह सभी ट्रैफ़िक का <3% है )। शायद वहां पर ऐसे मामले जहां मुझे लेखन प्रदर्शन को अनुकूलित करना था
  • गैर-असीसी वर्णों का अस्तित्व: आप XML में एन्कोडिंग के रूप में utf-8 का उपयोग कर सकते हैं
  • बाइनरी डेटा का अस्तित्व: बेस 64 एन्कोडिंग का उपयोग करने की आवश्यकता होगी
  • फ़ाइल नाम डेटा: आप एक्सएमएल में इस अंदर के क्षेत्र को समाहित कर सकते हैं

आवेदन / json

  • डेटा आकार: XML से अधिक कॉम्पैक्ट कम, अभी भी टेक्स्ट, लेकिन आप संपीड़ित कर सकते हैं
  • गैर-असीसी वर्ण: जेसन यूटीएफ -8 है
  • बाइनरी डेटा: बेस 64 ( json-binary-question भी देखें)
  • फ़ाइल नाम डेटा: जेसन के अंदर अपने क्षेत्र-अनुभाग के रूप में encapsulate

अपने संसाधन के रूप में बाइनरी डेटा

मैं अपनी संपत्ति / संसाधन के रूप में बाइनरी डेटा का प्रतिनिधित्व करने की कोशिश करता हूं। यह एक और कॉल जोड़ता है लेकिन सामान को बेहतर बनाता है। उदाहरण छवियां:

POST /images
Content-type: multipart/mixed; boundary="xxxx" 
... multipart data

201 Created
Location: http://imageserver.org/../foo.jpg  

बाद के संसाधनों में आप बस बाइनरी संसाधन को लिंक के रूप में रेखांकित कर सकते हैं:

<main-resource&gt
 ...
 <link href="http://imageserver.org/../foo.jpg"/>
</main-resource>

टी एल; डॉ

सारांश; यदि आपके पास संचारित करने के लिए बाइनरी (गैर-अल्फान्यूमेरिक) डेटा (या एक महत्वपूर्ण आकार का पेलोड) है, तो multipart/form-data उपयोग करें। अन्यथा, application/x-www-form-urlencoded

आपके द्वारा उल्लिखित MIME प्रकार HTTP POST अनुरोधों के लिए दो Content-Type शीर्षलेख हैं जो उपयोगकर्ता-एजेंट (ब्राउज़र) को समर्थन देना चाहिए। उन दोनों प्रकार के अनुरोधों का उद्देश्य सर्वर पर नाम / मूल्य जोड़े की एक सूची भेजना है। प्रेषित किए जा रहे डेटा के प्रकार और मात्रा के आधार पर, विधियों में से एक दूसरे की तुलना में अधिक कुशल होगा। समझने के लिए, आपको यह देखना होगा कि प्रत्येक कवर के तहत क्या कर रहा है।

application/x-www-form-urlencoded लिए, सर्वर पर भेजे गए HTTP संदेश का शरीर अनिवार्य रूप से एक विशाल क्वेरी स्ट्रिंग है - नाम / मान जोड़े ampersand ( & ) द्वारा अलग किए जाते हैं, और नाम मूल्यों से अलग होते हैं प्रतीक बराबर ( = )। इसका एक उदाहरण होगा:

MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

specification अनुसार:

[आरक्षित और] गैर-अल्फान्यूमेरिक वर्णों को '% एचएच' द्वारा प्रतिस्थापित किया गया है, एक प्रतिशत चिह्न और दो हेक्साडेसिमल अंक वर्ण के ASCII कोड का प्रतिनिधित्व करते हैं

इसका मतलब यह है कि प्रत्येक गैर-अल्फान्यूमेरिक बाइट जो हमारे मानों में से एक में मौजूद है, के लिए यह तीन बाइट्स को प्रस्तुत करने जा रहा है। बड़ी बाइनरी फाइलों के लिए, पेलोड को तीन गुना अधिक अक्षम किया जा रहा है।

यही वह जगह है जहां multipart/form-data आता है। नाम / मूल्य जोड़ों को प्रेषित करने की इस विधि के साथ, प्रत्येक जोड़ी को एक एमआईएमई संदेश में "भाग" के रूप में दर्शाया जाता है (जैसा कि अन्य उत्तरों द्वारा वर्णित है)। भागों को एक विशेष स्ट्रिंग सीमा से अलग किया जाता है (विशेष रूप से चुना जाता है ताकि यह सीमा स्ट्रिंग किसी भी "मान" पेलोड में न हो)। प्रत्येक भाग में एमआईएम हेडर का अपना सेट होता है जैसे Content-Type , और विशेष रूप से Content-Disposition , जो प्रत्येक भाग को अपना "नाम" दे सकता है। प्रत्येक नाम / मूल्य जोड़ी का मान टुकड़ा एमआईएमई संदेश के प्रत्येक भाग का पेलोड है। एमआईएमई स्पेक हमें मूल्य पेलोड का प्रतिनिधित्व करते समय अधिक विकल्प देता है - हम बैंडविड्थ को बचाने के लिए बाइनरी डेटा का अधिक कुशल एन्कोडिंग चुन सकते हैं (जैसे बेस 64 या यहां तक ​​कि कच्ची बाइनरी)।

क्यों multipart/form-data हर समय उपयोग नहीं करते? लघु अल्फान्यूमेरिक मानों (जैसे अधिकांश वेब रूपों) के लिए, सभी MIME शीर्षकों को जोड़ने का ओवरहेड अधिक कुशल बाइनरी एन्कोडिंग से किसी भी बचत से काफी अधिक होने जा रहा है।


सबसे पहले यहां पर PARA पढ़ें!

मुझे पता है कि यह 3 साल बहुत देर हो चुकी है, लेकिन मैट (स्वीकृत) उत्तर अपूर्ण है और अंततः आपको परेशानी में डाल देगा। यहां कुंजी यह है कि, यदि आप multipart/form-data का उपयोग करना चुनते हैं, तो सीमा को फ़ाइल डेटा में दिखाई नहीं देना चाहिए जिसे सर्वर अंततः प्राप्त करता है।

यह application/x-www-form-urlencoded लिए कोई समस्या नहीं है, क्योंकि कोई सीमा नहीं है। x-www-form-urlencoded भी एक मनमानी बाइट को तीन 7BIT बाइट्स में बदलने के सरल लाभ से बाइनरी डेटा को हमेशा संभाल सकता है। अक्षम, लेकिन यह काम करता है (और ध्यान दें कि फाइलनामों के साथ-साथ बाइनरी डेटा भेजने में सक्षम नहीं होने के बारे में टिप्पणी गलत है; आप इसे एक और कुंजी / मूल्य जोड़ी के रूप में भेजते हैं)।

multipart/form-data साथ समस्या यह है कि सीमा विभाजक फ़ाइल डेटा में मौजूद नहीं होना चाहिए ( RFC2388 देखें; सेक्शन 5.2 में उचित समस्या वाले एमआईएम प्रकार के लिए एक लंगड़ा बहाना भी शामिल है जो इस समस्या से बचाता है)।

तो, पहली बार, multipart/form-data किसी भी फ़ाइल अपलोड, बाइनरी या अन्यथा में कोई भी मूल्य नहीं है। यदि आप अपनी सीमा सही तरीके से नहीं चुनते हैं, तो आपको अंततः एक समस्या होगी, भले ही आप सादे पाठ या कच्चे बाइनरी भेज रहे हों - सर्वर को गलत जगह पर एक सीमा मिलेगी, और आपकी फ़ाइल को छोटा कर दिया जाएगा, या POST असफल हो जायेगी।

कुंजी एन्कोडिंग और सीमा चुनना है जैसे कि आपके चयनित सीमा वर्ण एन्कोडेड आउटपुट में प्रकट नहीं हो सकते हैं। base64 का उपयोग करना एक आसान समाधान है (कच्चे बाइनरी का उपयोग करें)। base64 3 में मनमानी बाइट्स को चार 7-बिट वर्णों में एन्कोड किया गया है, जहां आउटपुट कैरेक्टर सेट [A-Za-z0-9+/=] (यानी अल्फान्यूमेरिक्स, या '+', '/', '=') है । = एक विशेष मामला है, और केवल एन्कोडेड आउटपुट के अंत में दिखाई दे सकता है, एक एकल = या एक डबल == । अब, अपनी सीमा को 7-बिट ASCII स्ट्रिंग के रूप में चुनें जो base64 आउटपुट में दिखाई नहीं दे सकता है। नेट पर आपके द्वारा देखे जाने वाले कई विकल्प इस परीक्षण में असफल होते हैं - एमडीएन फॉर्म docs , उदाहरण के लिए, बाइनरी डेटा भेजते समय सीमा के रूप में "ब्लॉब" का उपयोग करें - अच्छा नहीं। हालांकि, "ब्लॉब!" जैसे कुछ base64 आउटपुट में कभी नहीं दिखाई देगा।







http-headers