मैं HTTP GET क्वेरी स्ट्रिंग लंबाई सीमाओं से कैसे निपट सकता हूं और अभी भी Restful बनना चाहता हूं?


84

जैसा कि इसमें घोषित किया गया है http://www.boutell.com/newfaq/misc/urllength.html , HTTP क्वेरी स्ट्रिंग की सीमित लंबाई है। यह क्लाइंट (फ़ायरफ़ॉक्स, आईई, ...), सर्वर (अपाचे, आईआईएस, ...) या नेटवर्क उपकरण (ऐप्लिकेटिव फ़ायरवॉल, ...) द्वारा सीमित किया जा सकता है।

आज मैं इस समस्या का सामना एक खोज प्रपत्र के साथ करता हूँ। हमने बहुत सारे फ़ील्ड के साथ एक खोज फ़ॉर्म विकसित किया है, और इस फॉर्म को सर्वर को GET अनुरोध के रूप में भेजा जाता है, इसलिए मैं परिणामी पृष्ठ को बुकमार्क कर सकता हूं।

हमारे पास इतने सारे क्षेत्र हैं कि हमारा क्वेरी स्ट्रिंग 1100 बाइट्स लंबा है, और हमारे पास फ़ायरवॉल है जो HTTP GET के अनुरोध को 1024 से अधिक बाइट्स के साथ छोड़ देता है। हमारा सिस्टम प्रशासक हमें इसके बजाय POST का उपयोग करने की सलाह देता है ताकि कोई सीमा न रहे।

निश्चित रूप से, POST काम करेगा, लेकिन मैं वास्तव में एक GET के रूप में एक खोज महसूस करता हूं और POST नहीं। इसलिए मुझे लगता है कि मैं यह सुनिश्चित करने के लिए हमारे क्षेत्र के नामों की समीक्षा करूंगा कि स्ट्रिंग स्ट्रिंग बहुत लंबी नहीं है, और यदि मैं नहीं कर सकता तो मैं व्यावहारिक रहूंगा और POST का उपयोग करूंगा।

लेकिन क्या रेस्टफुल सेवाओं के डिजाइन में कोई दोष है? यदि हमारे पास GET अनुरोध में सीमित लंबाई है, तो मैं बड़ी वस्तुओं को Restful webservice में कैसे भेज सकता हूं? उदाहरण के लिए, यदि मेरे पास एक प्रोग्राम है जो एक फ़ाइल के आधार पर गणना करता है, और मैं इस तरह एक RESTful webservice प्रदान करना चाहता हूं http://compute.com?content=<base64 file>:। यह काम नहीं करेगा क्योंकि क्वेरी स्ट्रिंग में असीमित लंबाई नहीं है।

मैं थोड़ा हैरान हूँ ...


2
आपके संदर्भ के संदर्भ में बाकी का क्या मतलब है? या विरोधाभास: क्यों GET आराम है और POST नहीं है? क्योंकि GET का निर्माण सरल स्ट्रिंग संघनन का उपयोग करके किया जा सकता है? क्वेरी लंबाई सीमा क्षुधा में गतिशील मेमोरी आवंटन से बचने के लिए है जो तेजी से काम करने का इरादा रखते हैं।
११

5
जब मैं कोई खोज करना चाहता हूं, तो मैं कुछ बनाना, हटाना या अद्यतन नहीं करना चाहता, मैं केवल डेटा पुनर्प्राप्त करना चाहता हूं, इसलिए मुझे POST, DELETE या PUT का उपयोग नहीं करना चाहिए, और मुझे GET का उपयोग करना चाहिए। इस तरह से मैं REST को समझ गया लेकिन मुझे इसके बारे में गलत हो सकता है
cbliard

खोज के लिए GET उपयुक्त नहीं है, क्योंकि समय के साथ खोज के परिणाम बदल सकते हैं। वेब इन्फ्रास्ट्रक्चर अक्सर GET अनुरोधों की कैशिंग की अनुमति देता है। यदि आप GET का उपयोग करते हैं तो आपको खोजों के लिए पुराने बासी परिणाम प्राप्त होने का जोखिम है। POST वह तरीका है, जैसा कि नीचे सुझाया गया है।
occulus

15
सब कुछ ओवरटाइम बदल जाता है ( en.wikipedia.org/wiki/Impermanence ), ऐसा ब्रह्मांड की प्रकृति है ... लेकिन खोज के लिए GET का उपयोग किया जाना चाहिए क्योंकि "खोज कार्रवाई" के परिणाम नहीं बदलते हैं
Luxspes

जवाबों:


51

आपके विवरण के आधार पर, IMHO आपको एक POST का उपयोग करना चाहिए। POST सर्वर पर डेटा डालने और कुछ मामलों में, एक उत्तर प्राप्त करने के लिए है। आपके मामले में, आप एक खोज करते हैं (सर्वर को एक प्रश्न भेजें) और उस खोज का परिणाम प्राप्त करें (क्वेरी परिणाम प्राप्त करें)।

GET की परिभाषा कहती है कि इसका उपयोग पहले से मौजूद संसाधन को पुनः प्राप्त करने के लिए किया जाना चाहिए। परिभाषा के अनुसार, POST एक नया संसाधन बनाना है। यह वही है जो आप कर रहे हैं: सर्वर पर एक संसाधन बनाना और इसे पुनः प्राप्त करना! यहां तक ​​कि अगर आप खोज परिणाम को संग्रहीत नहीं करते हैं, तो आपने सर्वर पर एक ऑब्जेक्ट बनाया और इसे पुनर्प्राप्त किया। जैसा कि पीटरमम ने पूर्व में कहा था, आप ऐसा POST के साथ कर सकते हैं (क्वेरी परिणाम बनाएं और संग्रहीत करें) और फिर क्वेरी को पुनः प्राप्त करने के लिए GET का उपयोग करें, लेकिन यह अधिक व्यावहारिक है कि केवल POST करें और परिणाम पुनः प्राप्त करें।

उम्मीद है की यह मदद करेगा! :)


2
आप सही हैं, मैं इसे एक POST के रूप में देख सकता हूं क्योंकि खोज एक अस्थिर नव गणना संसाधन है। लेकिन मुझे अभी भी POST और GET के बीच की सीमा को देखने में समस्या है। यदि मैं पुस्तकालय में सभी विज्ञान-फ़िक्शन पुस्तकों की खोज करना चाहता हूं, तो मुझे मौजूदा संसाधनों का एक संग्रह मिलेगा, इसलिए मुझे एक GET का उपयोग करने का लालच है, लेकिन आप इसे एक POST के रूप में देखने का प्रस्ताव करते हैं क्योंकि खोज एक नया संसाधन है। इसलिए GET में क्वेरी स्ट्रिंग का उपयोग केवल डेटा प्रतिनिधित्व को बदलने के लिए किया जाना चाहिए, लेकिन डेटा को फ़िल्टर करने के लिए नहीं। क्या मैं सही हू?
cbliard

8
POST का उपयोग खोजों के लिए नहीं किया जाना चाहिए, GET का उपयोग किया जाना चाहिए, इस तरह से आप साझा कर सकते हैं और कैश कर सकते हैं, परिणामी URL और परिणाम, और आप इंटरनेट के बेहतर वास्तुकला का बेहतर लाभ उठाते हैं
Luxspes

37
यह उत्तर अधिक लगता है जैसे शब्दों के साथ खेलने की कोशिश करना। उस तर्क से, हम सब कुछ POST अनुरोधों के रूप में कर सकते हैं और अभी भी Restful हो सकते हैं।
सुपरटनस्की

9
यह उत्तर ऐसा लगता है जैसे कुछ वकील मुझसे बात करते हैं :-) प्रश्न वास्तव में है "मेरे पास एक GET मामला है, ठीक है। लेकिन मेरी क्वेरी स्ट्रिंग अनुमत लंबाई से अधिक है। मैं कैसे संभालूँ"। इस जवाब को नीचा दिखाना।
जी। स्टोयनेव

2
यदि उस तर्क का पालन किया गया है, तो हर अनुरोध एक संसाधन बना रहा है और इसे पुनर्प्राप्त कर रहा है।
एलेक्स

66

HTTP विनिर्देशन वास्तव में गणना के लिए संसाधन को डेटा भेजते समय POST का उपयोग करने की सलाह देता है

आपकी खोज एक संगणना की तरह लगती है, न कि किसी संसाधन की। यदि आप अभी भी चाहते हैं कि आप अपने खोज परिणामों को संसाधन के रूप में चाहते हैं तो उस विशिष्ट खोज परिणाम की पहचान करने के लिए एक टोकन बनाएं और उपयोगकर्ता एजेंट को उस संसाधन पर पुनर्निर्देशित करें।

आप कुछ समय के बाद खोज परिणाम टोकन हटा सकते हैं।

उदाहरण

POST /search
query=something&category=c1&category=c2&...

201 Created
Location: /search/01543164876

फिर

GET /search/01543164876

200 Ok
... your results here...

इस तरह, ब्राउज़र और प्रॉक्सी अभी भी खोज परिणामों को कैश कर सकते हैं लेकिन आप POST का उपयोग करके अपने क्वेरी मापदंडों को जमा कर रहे हैं।

संपादित करें

स्पष्टीकरण के लिए, 01543164876 यहां आपकी खोज का प्रतिनिधित्व करने वाले संसाधन के लिए एक अद्वितीय आईडी का प्रतिनिधित्व करता है। उन 2 अनुरोधों का मूल रूप से मतलब है: इन मानदंडों के साथ एक नई खोज ऑब्जेक्ट बनाएं, फिर बनाए गए खोज ऑब्जेक्ट के साथ जुड़े परिणामों को पुनः प्राप्त करें।

यह आईडी प्रत्येक नए अनुरोध के लिए बनाई गई एक अद्वितीय आईडी हो सकती है। इसका मतलब यह होगा कि आपका सर्वर "खोज" वस्तुओं को लीक करेगा और आपको कैशिंग रणनीति के साथ उन्हें नियमित रूप से साफ करना होगा।

या यह वास्तव में उपयोगकर्ता द्वारा पूछी गई खोज का प्रतिनिधित्व करने वाले सभी खोज मानदंडों का हैश हो सकता है। यह आपको आईडी का पुन: उपयोग करने की अनुमति देता है क्योंकि खोज को पुन: उपयोग करने से मौजूदा आईडी वापस आ जाएगी जो पहले से ही कैश हो सकती है (या नहीं)।


क्वेरी को बुकमार्क करने के बारे में यह ओपी आवश्यकता को कैसे संबोधित करता है?
Rhubarb

2
@ रुर्ब यह किसी दिए गए खोज के लिए एक संसाधन बनाकर इसे स्पष्ट रूप से संबोधित करता है।
मौलिक

3
यह परिणाम धीमा कर देगा। एक पोस्ट करें और फिर एक GET करें। यह खोज लाने के लिए कम से कम 300ms जोड़ देगा।
13

स्रोत से लिंक मर चुका है
एमोब

मैं उलझन में हूँ, सर्वर POST और GET के बीच क्या करता है? क्या यह सर्वर पर खोज डेटा को कैश करता है और बस GET अनुरोध के आने की प्रतीक्षा करता है? ऐसा करने के लिए कुछ अनोखी आईडी का उपयोग करना होगा, ताकि आप कैश को पुनः प्राप्त कर सकें। आपका उत्तर अच्छा है, लेकिन निश्चित रूप से पूरा नहीं हुआ है। और कैश का उपयोग करने से चीजें कम निष्क्रिय हो जाएंगी।
अलेक्जेंडर मिल्स

5

REST चीजों को करने का एक तरीका है, प्रोटोकॉल नहीं। यहां तक ​​कि अगर आप वास्तव में एक GET है, तो POST को नापसंद करते हैं, तो यह काम करेगा।

यदि आप GST, POST, आदि की "मानक" परिभाषा के साथ बने रहेंगे, तो शायद POST को एक क्वेरी मानें, उस क्वेरी को सर्वर पर क्वेरी आईडी के साथ संग्रहीत किया जाएगा और क्वेरी को बाद में GET द्वारा आईडी के साथ अनुरोध किया जाएगा।


4

अपने उदाहरण के बारे में:http://compute.com?content={base64file} मैं POST का उपयोग करता हूँ क्योंकि आप "कुछ" को अपलोड करने के लिए गणना कर रहे हैं। मेरे लिए यह "कुछ" एक साधारण पैरामीटर के रूप में अधिक संसाधन जैसा लगता है।

सामान्य खोज में इसके विपरीत मैं GET और मापदंडों के साथ रहना शुरू करूंगा। आप एपि-क्लाइंट के लिए अपने एपि के साथ परीक्षण और खेलने के लिए इसे बहुत आसान बनाते हैं। जितना संभव हो, केवल पढ़ने के लिए पहुँच (जो ज्यादातर मामलों में यातायात का बहुमत है) बनाओ!

लेकिन बड़ी क्वेरी स्ट्रिंग की दुविधा जीईटी की एक वैध सीमा है। यहाँ मैं व्यावहारिक जाऊँगा, जब तक आप इस सीमा को हिट नहीं करते हैं, GET और url-params के साथ चलते हैं। यह 98% खोज-मामलों में काम करेगा। यदि आप इस सीमा से टकराते हैं तो केवल पेलोड (माइम-प्रकार के साथ) पोस्ट करेंContent-Type: application/x-www-form-urlencoded ) के ।

क्या आपको और वास्तविक दुनिया के उदाहरण मिले हैं?


अभिकलन एक वास्तविक दुनिया उदाहरण था। खोज के बारे में, हम कई विक्रय बिंदुओं पर लेनदेन की खोज करना चाहते हैं, इसलिए हम विक्रय बिंदुओं का चयन करने के लिए एक नई ब्राउज़र विंडो खोलते हैं। और जब हम सत्यापित करते हैं तो हम चयनित विक्रय बिंदुओं को सेट करने के लिए खोज प्रपत्र में छिपे हुए पैरामीटर को संशोधित करते हैं। यदि वास्तव में उनमें से कई हैं, तो परिणामी खोज अनुरोध में बहुत लंबी क्वेरी स्ट्रिंग होगी।
सिलबर्ड

4

GET के चारों ओर भ्रम एक ब्राउज़र सीमा है। अगर आप A2A या P2P एप्लिकेशन के लिए एक RESTful इंटरफ़ेस बना रहे हैं तो आपके GET की लंबाई को कोई सीमा नहीं है।

अब, यदि आप अपने RESTful इंटरफ़ेस (विकास / डिबगिंग के दौरान उर्फ) को देखने के लिए एक ब्राउज़र का उपयोग करना चाहते हैं, तो आप इस सीमा में चलेंगे, लेकिन इसको प्राप्त करने के लिए कुछ उपकरण हैं।


6
"GET एक ब्राउज़र सीमा है" - यह एक सर्वर सीमा भी है। आपको सभी वेब सर्वर सीमा लागू करने वाले मिल जाएंगे, और यदि आपके पास सीडीएन हैं तो वे एक सीमा भी लागू कर सकते हैं। अनुरोध को पूरा करने के लिए अन्य साधनों का उपयोग करने से सर्वर सीमाएँ कम नहीं होंगी।
कोर्टनी माइल्स

0

यह थोड़ा आसान है। POST का उपयोग करें। HTTP GET के लिए URL लंबाई पर एक सीमा नहीं लगाता है लेकिन सर्वर करते हैं। व्यावहारिक रहें और एक POST के साथ उस पर काम करें।

आप एक GET बॉडी (जिसकी अनुमति है) का भी उपयोग कर सकते हैं, लेकिन यह एक डबल-धम्म है कि यह सही उपयोग नहीं है और शायद सर्वर की समस्या है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.