axios でURLパラメータのエンコード処理を変更するには

なぜエンコード処理を変更するのか?
→ RFC3986の予約文字が、いくつかエンコードされないから。

ということで、実際に axios で試してみた要求がこちら。

axios.get('/test', { params: { a: ":/?#[]@!$&'()*+,;=" } });

結果がこちら。

/test?a=:%2F%3F%23[]%40!$%26%27()*%2B,%3B%3D

エンコードされていない文字(:[]!$()*,)がありますね。
こうなっている背景が確認できていませんが、対策しないまま受け付けてくれないサーバーがあったとしても、基本的には違反しているクライアント側(axiosを使っている側)が直すことになるんじゃないかと思います。
そして、axios側はエンコード処理を設定できるようにしてくれているので、その部分を設定すれば OK です。

ということで、axios 0.23.0 で試してみました。
要求毎に設定するとメンテナンス性が下がるので、ログの場合と同様に共通化で対応します。

qs を使う

qs 6.10.1 で試してみました。
デフォルトは RFC3986 に従い、オプションで RFC1738 にできます。

import axios from 'axios';
import qs from 'qs';

function paramsSerializer(params: any) {
  return qs.stringify(params);
// return qs.stringify(params, { format: 'RFC1738' });
}

axios.interceptors.request.use(
  config => ({
    ...config,
    paramsSerializer,
  }),
);

結果は以下の通り、エンコードされました。

/test?a=%3A%2F%3F%23%5B%5D%40%21%24%26%27%28%29%2A%2B%2C%3B%3D

jQuery を使う

ついでに jQuery 3.6.0 でも試してみました。
想定する用途が違うからか、何文字かエンコードされなかったので、qs にしておけば良さそうです。

import $ from 'jquery';

function paramsSerializer(params: any) {
  return $.param(params);
}

axios.interceptors.request.use(
  config => ({
    ...config,
    paramsSerializer,
  }),
);

結果は

/test?a=%3A%2F%3F%23%5B%5D%40!%24%26%27()*%2B%2C%3B%3D

コメント