js で http query をオブジェクトからビルドする
JavascriptのオブジェクトをURLのGET引数に変換したいときには、npm 探しますか? ライブラリ探しますか?
URLSearchParams ができています。
GETパラメタを扱うときは、これがあれば、だいたい解決する
https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
URLSearchParams は 古くは querystring と呼ばれた関数です。パワーアップして帰ってきました。
https://developer.mozilla.org/en-US/docs/Archive/Add-ons/Add-on_SDK/High-Level_APIs/querystring
Object( hash ) → queryString の変換
手軽で便利な使い方です。
new URLSearchParams( {a:1 , b:3} ).toString(); 'a=1&b=3'
便利ですね。
ネストには注意
そのままでは、ネストできません。ネストできません。
オブジェクトのネスト:
Object文字列になります。
> new URLSearchParams( {a:{x:10,y:11}, b:3} ).toString(); 'a=%5Bobject+Object%5D&b=3'
残念。toString されているだけです。
配列でネスト
配列も同じです。
> a = new URLSearchParams( {a:[10,11], b:3} ).toString(); 'a=10%2C11&b=3' > decodeURIComponent(a) 'a=10,11&b=3' >
残念ですね。toStringされているだけです。
URLのGETパラメタを正しく扱うので、同名のパラメタが2個あっても良い。
これもオブジェクトを扱うときの注意点なのですが、キー名はダブることがあります。
オブジェクトではダブリを扱えないのですが、URLSearchParamsは扱えてしまいます。
> new URLSearchParams("start=大阪&via=心斎橋&via=難波&dest=天王寺") URLSearchParams { 'start' => '大阪', 'via' => '心斎橋', 'via' => '難波', 'dest' => '天王寺' }
Objectをパラメタ変換しようとしたり逆にObjectで取り出そうとしたとき、ネストをどう扱うか、ダブるキー名をパラメタに含めるなど、キーを扱うときは注意を払う必要があります。
Object {} と URLSearchParams は等価交換できないのです。配列になってくれたりしないのです。
iteratorで使うURLSearchParams
> new URLSearchParams("start=大阪&via=心斎橋&via=難波&dest=天王寺").entries() URLSearchParams Iterator { [ 'start', '大阪' ], [ 'via', '心斎橋' ], [ 'via', '難波' ], [ 'dest', '天王寺' ] }
こちらは、全パラメータをきれいにiterator で回るのです。
Iterator からさらオブジェクトへ(2021-11-19追記)
Iterator のママでは少々使いにくいので Object.fromEntries を使って便利に使う。
var cond = Object.fromEntries(new URLSearchParams(window.location.search)) cond['start']
Object.fromEntries はバージョンを選ぶので、polyfill したほうが無難。
node の組込querystringなら、配列になってくれる
https://nodejs.org/api/querystring.html
querystring.parse("start=大阪&via=心斎橋&via=難波&dest=天王寺") [Object: null prototype] { start: '大阪', via: [ '心斎橋', '難波' ], dest: '天王寺' }
node 組み込みの querystring ならば、配列になってくれていたので、このほうが便利だったと思うんですね。
きれいなオブジェクトになる querystring
URLSearchParams と違って node の querystring ならオブジェクトになってきれいだと思う。
> a = querystring.parse("start=大阪&via=心斎橋&via=難波&dest=天王寺") [Object: null prototype] { start: '大阪', via: [ '心斎橋', '難波' ], dest: '天王寺' } > a [Object: null prototype] { start: '大阪', via: [ '心斎橋', '難波' ], dest: '天王寺' } > querystring.stringify(a) 'start=%E5%A4%A7%E9%98%AA&via=%E5%BF%83%E6%96%8E%E6%A9%8B&via=%E9%9B%A3%E6%B3%A2&dest=%E5%A4%A9%E7%8E%8B%E5%AF%BA' > decodeURI(querystring.stringify(a)) 'start=大阪&via=心斎橋&via=難波&dest=天王寺'
結論
URLSearchParamsが使えますが、ネストなど複雑なパラメタは扱いづらい。
node 環境下では querystring を使える。
ならば、ブラウザにnpmで互換パッケージをポーティングしたほうが便利なのかもしれません。