JavaScript 逆引き集 | URL 生成/解析(URLクラス)

JavaScript JavaScript
スポンサーリンク

URL クラスの基本 — const u = new URL('/a', 'https://example.com')

URL クラスは「URL文字列を安全に生成・分解」するための標準APIです。相対パスと基準URLを組み合わせて絶対URLを作れたり、protocol/host/pathname/searchParams などの部品を簡単に扱えます。文字列連結の失敗(スラッシュの重複・抜け、エンコード漏れ)を避けられるのが大きな利点です。


まずは生成と主要プロパティ

// 相対 + 基準で絶対URLを生成
const u = new URL("/a", "https://example.com"); // https://example.com/a

console.log(u.href);      // "https://example.com/a"
console.log(u.origin);    // "https://example.com"
console.log(u.protocol);  // "https:"
console.log(u.host);      // "example.com"(ポート込み)
console.log(u.hostname);  // "example.com"(ホスト名のみ)
console.log(u.port);      // ""(指定がなければ空)
console.log(u.pathname);  // "/a"
console.log(u.search);    // ""(クエリがなければ空)
console.log(u.hash);      // ""(ハッシュがなければ空)
JavaScript
  • 役割: URLの各部品を「安全に」読み書きできる。
  • 相対→絶対: new URL(relative, base) で確実に結合され、... の解決も自動。

よく使うテンプレート集

安全にパスを付け足す(スラッシュ問題を自動で解決)

const base = new URL("https://example.com/api/"); // 末尾スラッシュがあってもOK
const url = new URL("v1/users", base);            // → https://example.com/api/v1/users
JavaScript

クエリ操作は searchParams に任せる

const url = new URL("/search", "https://example.com");

// 追加・更新・複数値
url.searchParams.set("q", "apple");      // q=apple
url.searchParams.set("page", "2");       // page=2
url.searchParams.append("tag", "red");   // tag=red&...
url.searchParams.append("tag", "fresh"); // tag=fresh

console.log(url.toString());
// https://example.com/search?q=apple&page=2&tag=red&tag=fresh
JavaScript
  • ラベル: set は上書き、append は同キー追加。エンコードは自動。

部品を書き換えてリンクを生成

const url = new URL("https://example.com/shop?page=1#top");
url.pathname = "/shop/items";         // パス変更
url.searchParams.set("page", "2");    // クエリ更新
url.hash = "";                        // ハッシュ削除
console.log(url.href);                // https://example.com/shop/items?page=2
JavaScript

相対リンクを現在ページから解決

// ブラウザ環境なら現在ページを基準に
const img = new URL("images/photo.png", location.href);
console.log(img.href); // 現在ページのディレクトリからの絶対URL
JavaScript

ユーザー入力から安全にURLを組み立てる(try/catch)

function buildUrlSafe(pathSegment, base = "https://example.com") {
  try {
    // パスの1セグメントに特殊文字がある場合はエンコード(searchParamsとは別)
    const encoded = encodeURIComponent(pathSegment);
    return new URL(`/files/${encoded}`, base).href;
  } catch (e) {
    return null; // 不正なURLなら安全に失敗させる
  }
}
JavaScript

例題:API エンドポイント生成+フェッチ

function apiUrl(path, params = {}) {
  const url = new URL(path, "https://api.example.com/");
  for (const [k, v] of Object.entries(params)) {
    url.searchParams.set(k, String(v));
  }
  return url;
}

// 使い方
const url = apiUrl("v1/items", { page: 2, q: "banana" });
// https://api.example.com/v1/items?page=2&q=banana

const res = await fetch(url);
const data = await res.json();
JavaScript
  • ラベル: 文字列連結せずに URL クラスへ委ねると、スラッシュやエンコードの不安がなくなる。

例題:URL を分解して表示(解析ビュー)

function parseUrl(s) {
  try {
    const u = new URL(s);
    return {
      href: u.href,
      origin: u.origin,
      protocol: u.protocol,
      host: u.host,
      pathname: u.pathname,
      query: Object.fromEntries(u.searchParams.entries()),
      hash: u.hash,
    };
  } catch {
    return null;
  }
}

// 使い方
console.log(parseUrl("https://example.com/a/b?x=1&y=2#sec"));
// { href, origin, protocol, host, pathname: "/a/b", query: {x:"1", y:"2"}, hash:"#sec" }
JavaScript
  • ラベル: searchParams.entries() でクエリを簡単にオブジェクト化。

実務でのコツ

  • 文字列連結を避ける: new URL(relative, base) で結合すれば、スラッシュ有無や .. 解決も自動。
  • クエリは searchParams: 自前エンコード不要。複数値は append、取得は getAll
  • パスセグメントのエンコード: クエリ以外の「パスの一部」は encodeURIComponent で安全に。
  • 絶対 vs 相対の基準: ブラウザなら location.href を、サーバーサイドでも new URL(base, 'https://...') で明示基準を使う。
  • 検証と例外: 不正な文字列には new URL(...) が例外を出す。try/catch で処理を分けると安全。
  • HTTPS強制の例: プロトコルが http: の場合は url.protocol = 'https:' で統一(リダイレクトやリンク生成に有効)。

ありがちなハマりポイントと対策

  • 基準URLなしで相対を渡す → 例外:
    • 対策: 相対は必ず new URL(relative, base) の形にする。
  • パス結合のスラッシュ重複・欠落:
    • 対策: new URL("child", new URL("https://x/y/")) のようにクラスで結合。
  • パスの特殊文字で崩れる:
    • 対策: パスの「1セグメント」は encodeURIComponent。クエリは searchParams に任せる。
  • クエリの同キー上書きミス:
    • 対策: 同キー複数は append、単値は set。読み取りは getAll

練習問題(リンク生成ヘルパー)

// 1) 商品ページURLを生成: /products/:id?ref=...
function productUrl(id, ref) {
  const u = new URL(`/products/${encodeURIComponent(id)}`, location.origin);
  if (ref) u.searchParams.set("ref", ref);
  return u.href;
}

// 2) 現在URLからページ番号を取得(デフォルト1)
function currentPage() {
  const p = new URLSearchParams(location.search);
  return Number(p.get("page") || 1);
}

// 3) ページ番号を差し替えたURLを履歴追加
function goToPage(n) {
  const url = new URL(location.href);
  url.searchParams.set("page", String(n));
  history.pushState(null, "", url.toString());
}
JavaScript
  • ヒント: productUrlencodeURIComponent を使う理由は、IDにスラッシュやスペースが含まれていても安全に1セグメントとして扱うため。
タイトルとURLをコピーしました