【JavaScript】URLエンコードの使い分け!encodeURIとencodeURIComponentの完全理解

目次

概要

日本語やスペース、特殊記号を含む文字列をURLの一部として使用する場合、ブラウザが正しく解釈できる形式(パーセントエンコーディング)に変換する必要があります。

本記事では、用途に応じて使い分けるべき2つの標準メソッド encodeURIencodeURIComponent の違いを明確にし、ユーザー入力値を安全にSNSシェアボタンに反映させる実装例を紹介します。

仕様(入出力)

メソッドの比較

どちらも文字列を受け取り、エンコード済みの文字列を返しますが、変換対象となる文字の範囲が異なります。

メソッド意味・用途変換されない文字(主な例)
encodeURI(str)URL全体をエンコードする。
プロトコルやパス区切り文字は維持される。
A-Z a-z 0-9
; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #
encodeURIComponent(str)**URLの構成部分(パラメータ値など)**をエンコードする。
区切り文字(/?)もすべて変換する。
A-Z a-z 0-9
- _ . ! ~ * ' ( )
  • 入力: 文字列(String)
  • 出力: エスケープ処理された文字列(String)

基本の使い方

1. URL全体として扱いたい場合 (encodeURI)

URLとして機能する記号(: / ?)を残したまま、日本語などを変換します。

const url = 'https://example.com/検索/記事.html';
const encoded = encodeURI(url);

console.log(encoded);
// "https://example.com/%E6%A4%9C%E7%B4%A2/%E8%A8%98%E4%BA%8B.html"
// ※ https:// や / は変換されません

2. パラメータの値として埋め込む場合 (encodeURIComponent)

&= などの意味を持つ記号も含めて、すべて無害な文字列に変換します。クエリパラメータの値を作る際は必ずこちらを使用します。

const keyword = 'JavaScript & HTML';
const encoded = encodeURIComponent(keyword);

console.log(encoded);
// "JavaScript%20%26%20HTML"
// ※ スペースは%20、&は%26に変換されます

// URLに結合する例
const searchUrl = `https://example.com/search?q=${encoded}`;

コード全文(HTML / JavaScript)

ユーザーが入力した感想テキストを取得し、ハッシュタグを付与して「X(旧Twitter)」の投稿画面を開くシェアウィジェットの作成例です。

パラメータ値(text)を作成するため、encodeURIComponent を採用します。

HTML

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Custom Share Button</title>
    <style>
        .share-widget {
            font-family: sans-serif;
            max-width: 400px;
            padding: 20px;
            border: 1px solid #ccc;
            border-radius: 8px;
        }
        .input-area {
            width: 100%;
            height: 80px;
            margin-bottom: 10px;
            padding: 8px;
            box-sizing: border-box;
        }
        .btn-share {
            background-color: #000;
            color: #fff;
            border: none;
            padding: 10px 20px;
            border-radius: 20px;
            cursor: pointer;
            font-weight: bold;
        }
        .btn-share:hover {
            background-color: #333;
        }
    </style>
</head>
<body>

<div class="share-widget">
    <h3>記事の感想をシェア</h3>
    <textarea id="user-comment" class="input-area" placeholder="ここにコメントを入力..."></textarea>
    <button id="btn-post" class="btn-share">Xでポストする</button>
</div>

<script src="share.js"></script>
</body>
</html>

JavaScript

/**
 * シェアボタンのイベント設定
 */
const setupShareButton = () => {
    const button = document.getElementById('btn-post');
    const input = document.getElementById('user-comment');

    if (!button || !input) return;

    button.addEventListener('click', () => {
        // 1. 入力値の取得
        const comment = input.value;
        
        // 2. 投稿文の作成(固定ハッシュタグなどを付与)
        // 空入力の場合はデフォルト文言を設定
        const textToShare = comment ? `${comment} #TechLearning` : '学習中... #TechLearning';

        // 3. URIエンコード処理
        // パラメータ値として渡すため、encodeURIComponentを使用する
        const encodedText = encodeURIComponent(textToShare);

        // 4. シェア用URLの構築
        // X(Twitter)のIntent URL形式: https://twitter.com/intent/tweet?text=...
        const shareUrl = `https://twitter.com/intent/tweet?text=${encodedText}`;

        // 5. 新しいウィンドウで開く
        window.open(shareUrl, '_blank', 'width=550,height=400');
    });
};

// DOM読み込み完了後に実行
document.addEventListener('DOMContentLoaded', setupShareButton);

カスタムポイント

  • シェア先の変更:LINEで送る場合はURLスキーマを https://line.me/R/msg/text/?${encodedText} に変更することで対応可能です。
  • 現在ページのURLを含める:window.location.href を取得し、それも encodeURIComponent してから &url=... パラメータとして連結することで、記事URLも同時にシェアできます。
  • ウィンドウサイズの調整:window.open の第3引数で widthheight を指定することで、ポップアップウィンドウのサイズを制御できます。

注意点

  1. 使い分けのミス:encodeURI でパラメータ値をエンコードすると、&= が変換されずに残り、URLの構造が壊れてパラメータが正しく認識されなくなるリスクがあります。パラメータ値には必ず encodeURIComponent を使ってください。
  2. 二重エンコード:すでにエンコードされた文字列を再度エンコードすると、% 自体が %25 に変換され、復元できなくなります(例: %20%2520)。
  3. 古いメソッドの非推奨:古い記事で見かける escape() 関数は現在非推奨(Deprecated)です。文字化けの原因となるため使用しないでください。

応用

オブジェクトからクエリ文字列を一括生成する

複数のパラメータがある場合、手動で連結するのは手間です。URLSearchParams を使うと、エンコード処理を自動で行ってくれます。

const params = {
    text: 'こんにちは World',
    hashtags: 'JavaScript,Programming',
    url: 'https://example.com'
};

// URLSearchParamsが自動的にencodeURIComponent相当の処理を行う
const query = new URLSearchParams(params).toString();

console.log(query);
// "text=%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF+World&hashtags=JavaScript%2CProgramming&url=https%3A%2F%2Fexample.com"

まとめ

URLエンコードは、Web上でデータを安全に受け渡すための必須処理です。

  • URL全体を作るときは encodeURI(稀なケース)
  • パラメータの値を作るときは encodeURIComponent(頻出)

この原則を守ることで、日本語や特殊記号によるリンク切れやデータ破損を防ぐことができます。現代の開発では、応用で紹介した URLSearchParams も併せて活用することをお勧めします。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次