URLSearchParams なら RFC3986 に準拠すると思ったら微妙だった

qs 使えば RFC3986 の予約文字がエンコードされるのは確認できたのですが、今どきのブラウザなら URLSearchParams が使えるらしい。
パッケージ無く行けるなら楽ですよね。試しに大丈夫なのか DevTools のコンソール(Chrome 95.0.4638.69)で試してみました。

・・・アスターリスク(*)だけそのままですね。
どうやら application/x-www-form-urlencoded のエンコードになるようですが、

URLSearchParams objects will percent-encode anything in the application/x-www-form-urlencoded percent-encode set, and will encode U+0020 SPACE as U+002B (+).

https://url.spec.whatwg.org/#interface-urlsearchparams

The application/x-www-form-urlencoded percent-encode set contains all code points, except the ASCII alphanumeric, U+002A (*), U+002D (-), U+002E (.), and U+005F (_).

https://url.spec.whatwg.org/#application-x-www-form-urlencoded-percent-encode-set

の様に記載があるので、特に準拠するRFCは無いんでしょうか?
確かにエクスクラメーションマーク(!) などはエンコードされたので RFC2396 とは別っぽいんですよね。

ただ、MDN に encodeURIComponent を使って対応する例がありました。

// https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
function fixedEncodeURIComponent(str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}

URLSearchParams なら以下の感じでしょうか。
アスターリスクだけで良いのか確証が持てませんが。

function fixedURLSearchParams(obj) {
  return new URLSearchParams(obj)
    .toString()
    .replace(/[*]/g, function(c) {
      return '%' + c.charCodeAt(0).toString(16);
    });
}

今の所、qs にしておいた方が良さそうですね。

コメント