JavaScript Tips | 文字列ユーティリティ:URL 系 - URL エンコード

JavaScript JavaScript
スポンサーリンク

まず「URL エンコード」で何を守りたいのか

URL エンコードは、「URL の中に入れてはいけない(入れると誤解される)文字を、安全な形に変換すること」です。

日本語やスペース、?& などの記号を、そのまま URL に入れると、
ブラウザやサーバーが「区切り記号」と勘違いして、意味が壊れます。

だから、
本来は「データとしての文字」なのか
それとも「URL の構造を表す記号」なのか
を区別するために、「データ側」をエンコードしてあげる必要があります。


JavaScript で使う 2 つの基本関数

encodeURI と encodeURIComponent の違い

JavaScript には、URL エンコード用に代表的な 2 つの関数があります。

encodeURI("https://example.com/検索?q=テスト");
encodeURIComponent("検索");
JavaScript

ざっくり言うと、こう使い分けます。

  • encodeURI
    → 「URL 全体」をエンコードするときに使う(https://example.com/... みたいな形)。
    /?& など、「URL の構造に必要な記号」はそのまま残す。
  • encodeURIComponent
    → 「URL の一部(パラメータの値など)」をエンコードするときに使う。
    /?& も含めて、ほとんど全部エンコードする。

ここを間違えると、
「URL 全体を encodeURIComponent して壊す」
「パラメータ値を encodeURI して足りない」
という典型的なバグになります。


encodeURIComponent を使った「クエリパラメータ」の作り方

パラメータ値は必ず encodeURIComponent

一番よくあるのは、検索画面などで「クエリパラメータ」を作る場面です。

const keyword = "JavaScript 入門";
const url = "/search?q=" + encodeURIComponent(keyword);
// "/search?q=JavaScript%20%E5%85%A5%E9%96%80"
JavaScript

ここで重要なのは、keyword の部分だけを encodeURIComponent することです。

/search?q= という「URL の構造」はそのまま書き、
「値」の部分だけをエンコードします。

もし、エンコードしないとどうなるか。

const keyword = "A&B";
const url = "/search?q=" + keyword;
// "/search?q=A&B"
JavaScript

サーバー側から見ると、これは

  • q = "A"
  • 別パラメータ B(値なし)

のように解釈されてしまう可能性があります。

正しくはこうです。

const keyword = "A&B";
const url = "/search?q=" + encodeURIComponent(keyword);
// "/search?q=A%26B"
JavaScript

&%26 に変わることで、「これはデータです、区切り記号ではありません」と伝えられます。


encodeURI は「URL 全体」を扱うときに使う

すでに構造が決まっている URL を安全にする

例えば、外部から渡された URL を、そのままリンクとして使いたいけれど、
日本語やスペースが混ざっているかもしれない、というケース。

const rawUrl = "https://example.com/検索?q=テスト";
const safeUrl = encodeURI(rawUrl);
// "https://example.com/%E6%A4%9C%E7%B4%A2?q=%E3%83%86%E3%82%B9%E3%83%88"
JavaScript

ここで encodeURI がやっているのは、

  • 日本語部分を %E6... のような形に変換
  • ただし、https:///?= はそのまま残す

ということです。

もし、ここで encodeURIComponent を使うとどうなるか。

encodeURIComponent("https://example.com/検索?q=テスト");
// "https%3A%2F%2Fexample.com%2F%E6%A4%9C%E7%B4%A2%3Fq%3D%E3%83%86%E3%82%B9%E3%83%88"
JavaScript

:/?= まで全部エンコードされてしまい、
もはや「URL ではないただの文字列」になってしまいます。

URL 全体を扱うときは encodeURI、
URL の一部(特にパラメータ値)を扱うときは encodeURIComponent。

この切り分けがとても大事です。


実務でよくやる「クエリ文字列生成」ユーティリティ

オブジェクト → ?key=value&... を安全に作る

毎回 ?& を手でつなぐのは面倒なので、
オブジェクトからクエリ文字列を作る小さなユーティリティを用意しておくと便利です。

function toQueryString(params) {
  if (!params || typeof params !== "object") {
    return "";
  }

  const parts = [];

  for (const [key, value] of Object.entries(params)) {
    if (value == null) continue; // null / undefined はスキップ

    const encodedKey = encodeURIComponent(key);
    const encodedValue = encodeURIComponent(String(value));

    parts.push(`${encodedKey}=${encodedValue}`);
  }

  if (parts.length === 0) {
    return "";
  }

  return "?" + parts.join("&");
}
JavaScript

使い方はこうです。

const qs = toQueryString({
  q: "JavaScript 入門",
  page: 2,
  sort: "created_at desc",
});
// "?q=JavaScript%20%E5%85%A5%E9%96%80&page=2&sort=created_at%20desc"

const url = "/search" + qs;
JavaScript

ここでのポイントは、

  • key も value も 必ず encodeURIComponent する
  • null / undefined はパラメータとして付けない
  • 先頭に ? を付けるのはこの関数の責務にしてしまう

という設計にしておくことです。


設計として意識してほしいこと

「どこまでをユーティリティに任せるか」を決める

URL エンコードは、あちこちでバラバラに書き始めると、すぐに混乱します。

  • ここでは encodeURI を使っている
  • あそこでは encodeURIComponent を忘れている
  • 別のところでは replace(" ", "%20") だけしている

こうなると、「どこが安全でどこが危ないか」が分からなくなります。

なので、

export function toQueryString(params) { ... }
export function encodeQueryValue(value) {
  return encodeURIComponent(String(value ?? ""));
}
JavaScript

のように、「パラメータ値をエンコードする場所」を一箇所に決めてしまうのがおすすめです。

「エンコードしすぎ」と「しなさすぎ」の両方を避ける

  • URL 全体を encodeURIComponent して壊す
  • パラメータ値をエンコードせずに &= を混入させる

どちらもよくある事故です。

ルールはシンプルで、

  • URL の構造部分(パス・?&=)は自分で書く
  • ユーザー入力や動的な値は、必ず encodeURIComponent してから埋め込む

これだけ守れば、かなりのトラブルを避けられます。


ちょっとだけ手を動かしてみる

コンソールで、次の順番で試してみてください。

encodeURIComponent("A&B");
encodeURIComponent("JavaScript 入門");
encodeURI("https://example.com/検索?q=テスト");

toQueryString({ q: "A&B", page: 1 });
JavaScript

「どの文字が %xx 形式に変わるか」
「encodeURI と encodeURIComponent の違い」

を、自分の目で確かめてみてください。

そのうえで、自分のプロジェクトに

export function toQueryString(params) { ... }
JavaScript

のようなユーティリティを置いて、
「クエリ文字列を作るときは必ずここを通す」と決めてしまえば、
あなたの URL 周りのコードは、一気に“業務で安心して使えるレベル”に近づきます。

タイトルとURLをコピーしました