Last updated on

URLのクエリと百分率エンコード、`URLSearchParams`で組み立てる

  • Web
  • JavaScript
  • URL
  • URLSearchParams

ブラウザのアドレスに付く クエリ(? 以降)を、安全に組み立てるときの用語と URLSearchParams の扱いを、個人学習の整理としてまとめた。SNS シェア用 URL のような具体的な実装に入る前の、基礎編として読む想定です。

SNS シェア用の href として実際にどう組み立てるかは、SNSシェア用URLの組み立て に分けて整理しています。仕様の正本は URL Living Standard や URLSearchParams | MDN を参照すること。

デモページ: 本稿の考え方に近い SNS シェア用 URL(ty_appendQuery 相当と、表示中ページ向けの差し替え)の見本を置いたデモ — https://t2025-10-01vite.rea1i2e.net/demo/demo-share/


1. クエリの形

  • ? より左 … 多くの場合、サイトのスキーム・ホスト・パス。
  • ? より右 … 追加の指示を 名前=値&名前=値 のように列べた部分。セパレータは &、1セット内の区切りは =(イコール)。
  • 値の中に & や = や 日本語 など、区切りと衝突する文字をそのまま書けない。そこで 百分率エンコード(後述)が必要になる。

2. エンコード(なぜ必要か、二重にしない)

  • クエリの値として安全に送れる形に直す、というのがエンコードの考え方。多くの場合 encodeURIComponent や URLSearchParams に任せる。
  • 二重エンコード … すでに encode 済みの文字列を、もう一度 encode してしまうこと。例: encodeURIComponent を2回。値に % が異常に多い=要確認のサイン。

起きやすい例

  1. encodeURIComponent を手で2回。
  2. 既に encode 済みの文字列を URLSearchParams の set に渡す(さらに encode されがち)。
  3. クエリ全体や完成 href 全体を改めて encode。
  4. クライアントとサーバでそれぞれ encode するすれ違い。

目安: 生の文字列に対して一貫させる。完成 URL 全体を再 encode しない。

百分率エンコード(percent-encoding)とは

英語では percent-encoding、URL エンコードと呼ばれる文脈も多い。% に続く16進2桁で文字を表すルール。名前は パーセント記号 % から。


3. URLSearchParams は何をする API か

キーと値の組を持ち、toString() すると 百分率エンコード済みのクエリ文字列になる(先頭に ? は付かない)。ブラウザの JavaScript ではグローバル。Node では使える環境が増えている(要確認)。

  • set(name, value) … その name はこの1値に(同キー上書き)。
  • append(name, value) … 同じ name を複数(id=1&id=2 など)。

SNS の共有 URL の url / text、フォーム的な fetch の body などでよく使う。

作り方(4パターン)

  • 空: new URLSearchParams() → set / append
  • 文字列: new URLSearchParams('q=1&a=2')(? 付きでもよいことが多い)
  • オブジェクト: new URLSearchParams({ x: '1' })
  • 2次元配列: new URLSearchParams([['k','a'],['k','b']])(同キー複数)

読み出し

  • get('k') … 同キーが複数なら先頭
  • getAll('k') … 全部
  • has('k') … 有無
  • なければ get は null

set と append

  • 1キー1値にしたい → set
  • id=1&id=2 のように同キー複数 → append(set で上書きすると複数消えることが多い)

SNS 共有用 href の小さな例

toString() には ? が含まれないので、ベース URL(シェア用リンクの土台)のあとに '?' + params.toString() を足す。

const pageUrl = 'https://example.com/p';
const text = '押してね';
const sp = new URLSearchParams();
sp.set('url', pageUrl);
sp.set('text', text);
const href = 'https://twitter.com/intent/tweet?' + sp.toString();

(X の意図 URL は例。パラメータ名・エンドポイントは公式等で要確認。サービスごとの差や EJS / クライアントでの実装例は、SNSシェア用URLの組み立て で扱う。)

その他

  • 既存 URL の編集: new URL(location.href) の searchParams。
  • fetch の POST でフォーム風: Content-Type: application/x-www-form-urlencoded と body: new URLSearchParams({...}).toString()。
  • 列挙: for (const [k, v] of params) や forEach。
やりたいこと主に使うもの
クエリ文字列を生成set / append → toString()
同じキー複数append
1キー1値set
文字列をパースコンストラクタに文字列
今の URL の ? を変更new URL(...).searchParams

4. 学習の順序の目安

  1. クエリの形(? の右、キー=値&…)
  2. エンコードの意味と、二重にしない
  3. URLSearchParams(生の値 → toString())
  4. 必要に応じて URL#searchParams、fetch、Node との違い

参考