日本語の検索キーワードや商品名をそのままURLに書き込むことはできない — ひらがな・カタカナ・漢字はもちろん、スペースや&、?もURLの安全な文字集合には含まれておらず、percent-encodingに変換する必要がある。
なぜ漢字1文字が9文字の%表記になるのか
日本語の文字はまずUTF-8で3バイトに変換され、そのバイトごとに%XXという形式で書かれる。つまり漢字1文字が%E6%97%A5のように9文字の羅列になる。「東京」のようなわずか2文字の単語でも、エンコード後は18文字を超える長さになり、LINEやX(旧Twitter)でリンクを共有すると実際の内容以上に長く見える原因になる。
encodeURIComponentとencodeURIの違い
encodeURIComponentは&、?、=、/を含むほぼすべての構造的な記号をエンコードするため、検索ボックスの値のように?q=へ挿入する単一のパラメータ値に向いている。encodeURIはこれらの構造的な記号をそのまま残すため、すでに組み立て済みのURL全体をエンコードする用途に向いている。
よくある間違い
クエリ文字列全体をencodeURIComponentで一括エンコードすると、パラメータを区切る&や=まで%26や%3Dに変換されてしまい、サーバー側は複数のパラメータではなく1つの読めないパラメータを受け取ることになる。値ごとに個別にエンコードする必要がある。
こういうときに使う
- 日本語の検索キーワードや商品名をクエリパラメータに入れるとき。
- 動的な値(検索語、ID)を含むリンクを組み立てるとき。
- デバッグ:URLをデコードして実際にどんなデータが埋め込まれているか確認するとき。
エッジケース:二重エンコーディング
すでにpercent-encodingされた文字列を誤ってもう一度エンコードすると、%自体が%25に変換され、結果は二重にエンコードされた読めない文字列になる(%E6%97%A5が%25E6%2597%25A5になる)。フレームワークが自動的にURLをエンコードしているのに、コード側でも手動でencodeURIComponentを呼んでしまうと起きやすい。