Last updated on

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

  • Web
  • JavaScript
  • URL
  • URLSearchParams

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

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

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


1. クエリの形

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

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

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

起きやすい例

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

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

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

英語では percent-encodingURL エンコードと呼ばれる文脈も多い。% に続く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') … 有無
  • なければ getnull

setappend

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

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
  • fetchPOST でフォーム風: Content-Type: application/x-www-form-urlencodedbody: new URLSearchParams({...}).toString()
  • 列挙: for (const [k, v] of params)forEach
やりたいこと主に使うもの
クエリ文字列を生成set / appendtoString()
同じキー複数append
1キー1値set
文字列をパースコンストラクタに文字列
今の URL の ?変更new URL(...).searchParams

4. 学習の順序の目安

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

参考