2013-09-15(日) [長年日記]
■ HTTPでHashやArrayを送る手法に仕様は存在しない……の?
jQueryでこんなふうに書くと:
$.post('/', { hash: { foo: 'hoge', bar: 'fuga'}, array: ['baz', 'piyo'] });
サーバ側でこんなふうに受け取れて(これはSinatra):
post '/' do params.each do |key, val| puts "#{key}: #{val} as #{val.class}" end end
ちゃんとHashやArrayとしてアクセスできる:
hash: {"foo"=>"hoge", "bar"=>"fuga"} as Hash array: ["baz", "piyo"] as Array
ああこりゃ便利だね、で済ましてもいいんだけど、HTTP POSTの中身なんてただのバイト列なんだから型の情報なんて入ってるわけがない。その仕掛けはブラウザの開発者ツールあたりでどんなふうにエンコードされているのか覗いてみればすぐにわかって、上記のコードだとこんな感じになっているんだとわかる:
hash[foo]=hoge&hash[bar]=fuga&array[]=baz&array[]=piyo
最近プリミティブな(フレームワークを使っていない)PHPのコードを読む機会が多いんだけど、PHPerはこのテクをナチュラルに使っているようなのでPHP由来のプロトコルなのかなーと思うんだけど、さっきのコードはjQueryとSinatraだ。もちろんRailsでも使える。言語間をまたがって使える以上、なんらかの共通仕様があるのだろうと考えて調べてみたり、TwitterやFacebookで聞いてみたけど「これ!」っていうのがないような。
- web applications - What RFC defines arrays transmitted over HTTP? - Stack Overflow
- Uniform Resource Identifier (URI): Generic Syntax [RFC3986]
- php - Form input field names containing square brackets like field[index] - Stack Overflow
- square brackets in form names violate HTML specs? - PHP Development
少なくともRFCにはなってないようだ。キーと値を「=」でつないで、それらを「&」や「;」で並べる形式もURIの仕様にあるだけでその他の場面で使うのもわりと慣習っぽい? 「だいたいこんな感じ」で実装されてんのかなー。ご存知のかた、「これを押さえておけばOK」みたいな文書があれば教えていただきたく m(__)m