axiosで配列形式のパラメータのシリアライズ
axios を使って、ASP.NET Core に配列型のデータを送りたい場合のメモです。
foo[0].bar=1&foo[0].hoge=2&foo[1].bar=3&foo[1].hoge=4
のようなデータを送ります。
qsライブラリで配列形式を変換
qsを使って配列形式を変換する方法を使いました。
まず、元のデータはこのような形です。
import qs from 'qs'; const data = { foo: [ { bar:1, hoge:2 }, { bar:3, hoge:4 }, ] }; console.log(data);
{ foo : [ { bar: 1, hoge: 2 }, { bar: 3, hoge: 4 } ] }
これを qs.stringify で変換すると
import qs from 'qs'; const data = { foo: [ { bar:1, hoge:2 }, { bar:3, hoge:4 }, ] }; // encode: false オプションを指定しないとURLエンコードされた文字列になる const params = qs.stringify( data, { encode: false } ); console.log(params);
foo[0][bar]=1&foo[0][hoge]=2&foo[1][bar]=3&foo[1][hoge]=4
となり、惜しい形までは来ました。
2番めのカッコの部分を .bar .hoge にしたいのですが、簡単に変換できそうな方法を見つけられなかったので、encoder オプションを使って自力で変換してみました。
import qs from 'qs'; const data = { foo: [ { bar:1, hoge:2 }, { bar:3, hoge:4 }, ] }; const params = qs.stringify( data, { encoder: function (str, defaultEncorder, charset, type) { console.log(`Type=${type} Str=${str}`); if (type === 'key') { if (str.match(/¥[bar][/g)) { return str.replace(/¥[bar¥]/g, ".bar"); } if (str.match(/¥[hoge][/g)) { return str.replace(/¥[hoge¥]/g, ".hoge"); } } return str; }, // encode: false, // encode:true にすると encoderの関数が実行されないため } ); console.log(params);
Type=key Str=foo[0][bar] Type=value Str=1 Type=key Str=foo[0][hoge] Type=value Str=2 Type=key Str=foo[0][bar] Type=value Str=3 Type=key Str=foo[0][hoge] Type=value Str=4 foo[0].bar=1&foo[0].hoge=2&foo[1].bar=3&foo[1].hoge=4
axiosのparamSerializerに設定する
送信したいパラメータ形式ができたので、axios の paramSerializer にこの関数を設定して、送信時に配列を自動的にフォーマット変換してもらうようにします。
encoder オプションに関数を渡すように少し修正しました。
import qs from 'qs'; import axios from 'axios'; const data = { foo: [ { bar:1, hoge:2 }, { bar:3, hoge:4 }, ] }; function convertParam(str, defaultEncoder, charset, type) { console.log(`Type=${type} Str=${str}`); if ( type === 'key' ) { if (str.match(/¥[bar][/g)) { return str.replace(/¥[bar¥]/g, ".bar"); } if (str.match(/¥[hoge][/g)) { return str.replace(/¥[hoge¥]/g, ".hoge"); } } return str; } axios.get(url, { params, paramSerializer: (p) => qs.stringify(p, { encoder: convertParam }); });