डुप्लिकेट HTTP GET क्वेरी कुंजियों की आधिकारिक स्थिति


137

मुझे HTTP GET क्वेरी स्ट्रिंग डुप्लिकेट फ़ील्ड के साथ व्यवहार के बारे में आधिकारिक जानकारी प्राप्त करने में परेशानी हो रही है, जैसे

http://example.com/page?field=foo&field=bar 

और विशेष रूप से अगर आदेश रखा जाता है या नहीं। अधिकांश वेब-उन्मुख भाषाएं एक सरणी का उत्पादन करती हैं, जिसमें एक कुंजी "फ़ील्ड" से जुड़े फू और बार दोनों शामिल हैं, लेकिन मैं यह जानना चाहूंगा कि क्या इस बिंदु के बारे में आधिकारिक बयान मौजूद है (उदाहरण के लिए एक आरएफसी पर)। RFC 3986 में एक सेक्शन है 3.4. Query, जो कुंजी = वैल्यू पेयर को संदर्भित करता है, लेकिन ऑर्डर और डुप्लिकेट फ़ील्ड आदि की व्याख्या करने के तरीके के बारे में कुछ नहीं कहा जाता है। यह समझ में आता है, क्योंकि यह बैकेंड पर निर्भर है, और उस RFC के दायरे में नहीं ...

हालांकि एक वास्तविक मानक मौजूद है, मैं इसके लिए एक आधिकारिक स्रोत देखना चाहूंगा, बस जिज्ञासा से बाहर।


उस के बारे में भी सोच रहा था। दूसरी बात यह है कि POST बॉडी में उन लोगों के साथ क्वेरी स्ट्रिंग से पैरामीटर को मर्ज करने के बारे में कल्पना है।
थिलो

कोड रंच में, लोग कहते हैं कि कोई आदेश की गारंटी नहीं है। लेकिन उस धागे पुराना है और कोई भी इसे किसी भी तरह से पीठ अप: coderanch.com/t/357197/Servlets/java/getParameterValues-order
थिलो

1
क्वेरी स्ट्रिंग के क्रम को बनाए रखने वाले सर्वर के अलावा, ब्राउज़र द्वारा उन्हें DOM (या कुछ अन्य निश्चित) क्रम में भेजने के बारे में भी सवाल है।
थिलो

जवाबों:


112

इस पर कोई कल्पना नहीं है । आप जो चाहें वो कर सकते हैं।

विशिष्ट दृष्टिकोणों में शामिल हैं: पहले-दिए गए, अंतिम-दिए गए, सरणी-सभी, स्ट्रिंग-ज्वाइन-साथ-कॉमा-ऑफ-ऑल।

मान लें कि कच्चा अनुरोध है:

GET /blog/posts?tag=ruby&tag=rails HTTP/1.1
Host: example.com

फिर request.query['tag']भाषा या रूपरेखा के आधार पर, उपज के लिए विभिन्न विकल्प हैं :

request.query['tag'] => 'ruby'
request.query['tag'] => 'rails'
request.query['tag'] => ['ruby', 'rails']
request.query['tag'] => 'ruby,rails'

12
प्रश्न के बिंदु से अधिक, ['रेल', 'माणिक'] (अलग-अलग क्रम) का विकल्प भी है।
थिलो

2
एक निश्चित रूप से बड़ी संख्या में चीजें कर सकते हैं।
yfeldblum

7
.NET आपको एक सरणी के रूप में देगा (जब मैंने उस परीक्षण के आदेश के बारे में परवाह नहीं की है), तो PHP आपको हमेशा अंतिम और जावा देगा (कम से कम मैंने जिस सिस्टम पर जावा पर आधारित काम किया था) हमेशा पहला मूल्य। stackoverflow.com/questions/1809494/…
साइमनसिमिटी

17
यह HTTP पैरामीटर प्रदूषण नामक एक हमले पर आधारित है और इसका विश्लेषण OWASP द्वारा किया गया है: owasp.org/images/b/ba/AppsecEU09_CarettoniDiPaola_v0.8.pdf पेज 9 पर आपको 20 सिस्टमों की एक सूची मिलेगी और एक विवरण मिलेगा कि वे कैसे संभालते हैं। इस मुद्दे।
साइमनसिमिटी

1
@SimonSimCity इसके अलावा, अगर आप पैरामीटर नाम के लिए एक वैकल्पिक सूचकांक के साथ वर्ग कोष्ठक जोड़ते हैं, तो PHP वास्तव में एक सरणी बनाएगा।
मार्टिन एंडर

14

मैं पुष्टि कर सकता हूं कि PHP के लिए (कम से कम 4.4.4 संस्करण और नए में) यह इस तरह काम करता है:

GET /blog/posts?tag=ruby&tag=rails HTTP/1.1
Host: example.com

का परिणाम:

request.query['tag'] => 'rails'

परंतु

GET /blog/posts?tag[]=ruby&tag[]=rails HTTP/1.1
Host: example.com

का परिणाम:

request.query['tag'] => ['ruby', 'rails']

यह व्यवहार GET और POST डेटा के लिए समान है।


1
[]प्रत्यय वास्तव में अजीब व्यवहार की तरह लगता है, लेकिन अगर आप jQuery के माध्यम से एक तर्क के रूप में एक सरणी भेजने का प्रयास करें .ajax(), तो यह उन्हें स्वचालित रूप से आप के लिए एक ही तरह से जोड़ देंगे। ऐसा लगता है कि यह PHP उपयोगकर्ताओं के लाभ के लिए है।
इयान क्लार्क

4
@IanClark यह PHP कोडर्स के लिए सहज है - सादे PHP में, $foo[] = 1एक सरणी में जोड़ता है। Django (पायथन) भी यही काम करता है।
इज़्काता

Apache Tomcat पर यह सत्यापित कर सकता है कि यह अल्पविराम से जुड़ा हुआ तार देता है।
गौरव ओझा

8

yfeldblum का जवाब एकदम सही है।

बस एक पांचवें व्यवहार के बारे में एक नोट जो मैंने हाल ही में देखा था: विंडोज फोन पर , डुप्लिकेट क्वेरी कुंजी के साथ एक यूआरआई के साथ एक आवेदन खोलने के परिणामस्वरूप नेविगेशनफेल्ड किया जाएगा:

System.ArgumentException: उसी कुंजी के साथ एक आइटम पहले ही जोड़ा जा चुका था।

अपराधी है System.Windows.Navigation.UriParsingHelper.InternalUriParseQueryStringToDictionary(Uri uri, Boolean decodeResults)

तो सिस्टम आपको यह भी नहीं देना चाहेगा कि आप इसे जिस तरह से चाहते हैं, वह इसे मना करेगा। आप अपने स्वयं के प्रारूप (CSV, JSON, XML, ...) और uri-es-it को चुनने के लिए एकमात्र समाधान के साथ बचे हैं।


2
यह एक डिज़ाइन विकल्प के बजाय, उस फ़ंक्शन के आंतरिक बग जैसा लगता है। संभवत: फ़ंक्शन इसके द्वारा बनाए जा रहे शब्दकोश में डुप्लिकेट कुंजियों की जांच नहीं करता है। बेशक, शब्दकोशों को अद्वितीय कुंजियों की आवश्यकता होती है।
जगमग

1
तो क्लाइंट ब्राउज़र - सर्वर नहीं - इस स्थिति में एक त्रुटि फेंक रहा है? यह एक बग की तरह लगता है। मुझे आश्चर्य है कि अगर यह बग आज भी मौजूद है?
जॉन श्नाइडर

1
@JonSchneider हाँ, ग्राहक NavigationFailedऐसे URI के लिए फेंक रहा है। लेकिन, मुझे क्षमा करें, मैंने इस पोस्ट के एक महीने बाद विंडोज (फोन) डेवलपमेंट को छोड़ दिया और मैं मैकओएस (आईओएस) में चला गया, इसलिए मैं आजकल इस मुद्दे को ट्रैक करने में मदद नहीं कर सकता।
कूर

5

अधिकांश (सभी?) चौखटे कोई गारंटी नहीं देते हैं, इसलिए मान लें कि वे यादृच्छिक क्रम में वापस आ जाएंगे।

हमेशा सबसे सुरक्षित दृष्टिकोण अपनाएं।

उदाहरण के लिए, जावा HttpServlet इंटरफ़ेस: ServletRequest.html # getParameterValues

यहां तक ​​कि getParameterMap पद्धति पैरामीटर ऑर्डर के बारे में कोई भी उल्लेख नहीं करती है (एक java.util.Map इटरेटर का क्रम किसी पर भी निर्भर नहीं किया जा सकता है।)


3

आमतौर पर, डुप्लिकेट पैरामीटर मान जैसे

http://example.com/page?field=foo&field=bar

एक एकल क्वेरी पैरामीटर के परिणामस्वरूप जो एक सरणी है:

field[0]=='foo'
field[1]=='bar'

मैंने ASP, ASP.NET और PHP4 में यह व्यवहार देखा है।


वास्तव में, यह डी-फैक्टो मानक है, लेकिन जहां तक ​​मुझे लगता है कि इस पर कोई आधिकारिक निर्णय नहीं है। चूंकि मुझे विश्वास नहीं है कि यह मामला है, मैं इसे खोजने में असमर्थ हूं।
स्टेफानो बोरीनी

2
हां, शायद सभी ने उस व्यवहार को देखा है। सवाल यह था कि क्या वास्तव में कहीं निर्दिष्ट है।
थिलो

-1

मेरा भी यही सवाल था। मैं प्रश्नों को पार्स करने और उन्हें कठोर करने के लिए जावास्क्रिप्ट फ़ंक्शन लिख रहा हूं। मुझे नहीं पता कि अगर एक क्वेरी स्ट्रिंग में ब्रैकेट्स के साथ डुप्लिकेट नाम या नाम है, जैसे कि x [] = 1 & x [] = 2, मानक है हालांकि कुछ भाषा इन प्रारूप का समर्थन करती है।

लेकिन मुझे लगता है कि क्रोम और फ़ायरफ़ॉक्स में एक नया वर्ग नाम है URLSeachParamsऔर यह केवल सबसे सरल प्रारूप का समर्थन करता है name=value। यदि क्वेरी स्ट्रिंग में डुप्लिकेट नाम हैं, तो केवल पहले वाले को वापस getकरने की विधि URLSearchParams

इसलिए व्यक्तिगत रूप से, शायद सबसे सरल और कोई डुप्लिकेट नाम url भविष्य के लिए अधिक सुरक्षित नहीं है।


1
यदि क्वेरी स्ट्रिंग में डुप्लिकेट नाम हैं, तो URLSearchParams की विधि केवल पहले वाले को लौटाएं। यह सही नहीं है: आप सभी मूल्य को सरणी के रूप में पुनः प्राप्त कर सकते हैंURLSearchParams.getAll('x')
Blaise

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