HTTP GETクエリ文字列の重複フィールドの動作に関する信頼できる情報を見つけるのに問題があります。
http://example.com/page?field=foo&field=bar
特に注文が維持されるかどうか。ほとんどのWeb指向言語は、キー「フィールド」に関連付けられたfooとbarの両方を含む配列を生成しますが、この点に関する信頼できるステートメント(RFCなど)が存在するかどうかを知りたいです。 RFC 3986 にはセクション3.4. Query
、これはkey = valueペアを参照しますが、順序の解釈方法やフィールドの複製などについては何も言及されていません。これは理にかなっています。バックエンドに依存しており、そのRFCの範囲内ではないからです...
事実上の標準は存在しますが、好奇心から、信頼できるソースを探したいと思います。
そこに仕様なしがあります。好きなことをすることができます。
典型的なアプローチには、最初に与えられたもの、最後に与えられたもの、すべての配列、すべての文字列を結合するものが含まれます。
生のリクエストが次のとおりであるとします:
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'
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 data。
イフェルドブルムの答えは完璧です。
私が最近気づいた5番目の動作についてのメモ:Windows Phoneでは、クエリキーが重複するuriでアプリケーションを開くと、NavigationFailedが次のようになります:
System.ArgumentException:同じキーを持つアイテムが既に追加されていました。
原因はSystem.Windows.Navigation.UriParsingHelper.InternalUriParseQueryStringToDictionary(Uri uri, Boolean decodeResults)
です。
そのため、システムはユーザーが望むように処理することさえできず、禁止します。独自の形式(CSV、JSON、XMLなど)とuri-escape-itを選択する唯一のソリューションが残っています。
ほとんど(すべて?)のフレームワークは保証を提供しないため、ランダムな順序で返されると仮定します。
常に最も安全なアプローチを取ります。
たとえば、Java HttpServlet interface: ServletRequest.html#getParameterValues
getParameterMapメソッドでさえ、パラメーターの順序に関する記述を省略します(Java.util.Mapイテレーターの順序はどちらにも依存できません)。
通常、次のようなパラメータ値を複製します
http://example.com/page?field=foo&field=bar
結果は配列である単一のqueryStringパラメーターになります。
field[0]=='foo'
field[1]=='bar'
ASP、ASP.NET、およびPHP4でこの動作を見てきました。
同じ質問がありました。クエリを解析および文字列化するjavascript関数を書いています。一部の言語はこれらの形式をサポートしていますが、クエリ文字列に重複した名前があるか、x [] = 1&x [] = 2などの角かっこ付きの名前があるかどうかはわかりません。
しかし、私はChromeとFirefoxにはURLSeachParams
という名前の新しいクラスがあり、name=value
として最も単純な形式のみをサポートしています。クエリ文字列に重複する名前がある場合、 get
のURLSearchParams
メソッドは、最初のメソッドのみを返します。
個人的には、おそらく最も単純で重複しない名前のURLが将来的にははるかに安全です。