【JavaScript】URLエンコードとは?encodeURIComponentなどの使い方を初心者向けにわかりやすく解説
はじめに
皆さんは、URLエンコードという言葉を聞いたことがあるでしょうか。
Web開発をしていると、文字列をURLとして扱う場面がよくあります。
日本語や特殊文字が含まれる場合、そのままの形でURLとして指定するとエラーが起きたり、文字化けが発生したりするかもしれません。
こうした問題を回避するために使われるのが、URLエンコードです。
URLエンコードを行うと、特定のルールに従い文字列を変換し、安全に扱えるようになります。
本記事では、JavaScriptにおけるURLエンコードの基本概念と、実務でもよく使われるメソッドを丁寧に解説します。
初心者の方でもわかりやすいように具体例を用いながら説明しますので、ぜひ最後までお付き合いください。
エンコードの仕組みや注意点を知っておくと、余計なトラブルを回避できます。
また、実務シーンで何気なく扱っている処理がどのように動いているかがわかるため、仕組みに対する理解も深まるはずです。
この記事を読むとわかること
- URLエンコードとは何か、その基本的な仕組み
- JavaScriptでURLエンコードを行う代表的なメソッドの使い方
- 特殊文字を取り扱う際の具体的なポイント
- フォーム送信やAPIリクエストでの活用シーンと注意点
- 文字化けや2重エンコードなど、トラブルを回避するための知識
URLエンコードとは何か
URLエンコードとは、URLに含まれる文字列を安全に送受信するために、特定の符号形式に変換する処理のことです。
URLとして使える文字は、半角英数字や一部の記号に限られています。
一方で、実際の開発では日本語を含む文字列をGETパラメータやAPIのリクエストに含めたいケースが多くあります。
例えば、検索クエリとして日本語のキーワードを含める場合や、ユーザーから入力されたテキストが特殊文字を含む場合などです。
こうした文字はURLとしては直接利用できないため、対応するASCIIコードや16進数を使って変換し、URLとして通用する形にする必要があります。
ここで用いられる方式がURLエンコードです。
URLエンコードされると、文字列中のスペースが「%20」に変わったり、記号が「%3F」のように変わったりします。
これによって、ブラウザやサーバー側での混乱を防ぎ、正しくデータを受け渡せるようになるわけです。
エンコードの典型例を挙げると、以下のようになります。
#
→%23
?
→%3F
あ
→%E3%81%82
一見すると非常にややこしいのですが、要は人間が読むための文字列を機械が理解できる文字コードに置き換えているというイメージです。
JavaScriptでURLエンコードをする理由
JavaScriptに限らず、プログラミング言語ではいずれもURLエンコードが可能です。
しかしブラウザで動くJavaScriptの場合、特にクエリパラメータやURL生成の処理が身近に感じるでしょう。
例えば、フロントエンドからサーバーへAPIリクエストを送る際に、URLにパラメータを付けることがあります。
そのときに日本語や特殊記号を正しく扱わないと、サーバー側が意図しない文字列を受け取ってしまい、エラーや文字化けが発生するかもしれません。
加えて、JavaScriptにはエンコード専用の組み込み関数が用意されています。
わざわざ外部のライブラリを探す必要はなく、すぐに利用できるのが利点です。
短いコードでエンコードやデコードを実行できるため、URLパラメータの生成や解析をスムーズに行えるようになります。
ただし、JavaScriptのエンコード関連メソッドはいくつか種類があります。
encodeURI()
と encodeURIComponent()
の使い分けを誤ると、期待した変換が行われないこともあるので注意が必要です。
そういった点をきちんと理解しておけば、文字列の取り扱いで悩む時間を大幅に減らせるでしょう。
JavaScriptでURLエンコードを行うメソッド
JavaScriptには、URLエンコードやデコードを行うためのメソッドがいくつか存在します。
大きく分けると、次の4つがよく使われるでしょう。
encodeURI
encodeURI()
は、JavaScriptで文字列をURLとしてエンコードするために用いられます。
すでにURLとして意味を持つ一部の記号(例:?
, &
, =
など)はエンコード対象になりません。
そのため、URL全体をエンコードする際に使われることが多いです。
const originalUrl = "https://example.com/search?query=あいうえお"; const encodedUrl = encodeURI(originalUrl); console.log(encodedUrl); // "https://example.com/search?query=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A"
上記の例では、元のURLに含まれる日本語がエンコードされ、半角英数字や特定の記号はそのまま残っています。
URL全体を安全に利用したいときに、encodeURI()
を使うと便利です。
ただし、クエリパラメータとして追加する値に特殊文字が含まれる場合は、エンコードされずに残ってしまう可能性があります。
例えば、&
や =
をそのままにしておきたくないときは、後述する encodeURIComponent()
の方が適しています。
encodeURIComponent
encodeURIComponent()
は、URIコンポーネントをエンコードするためのメソッドです。
先ほどの encodeURI()
と比較すると、より幅広い文字がエンコードの対象になります。
URLパラメータ部分に値を埋め込むようなケースでは、encodeURIComponent()
を使うのが一般的です。
const baseUrl = "https://example.com/search?query="; const keyword = "あいうえお=テスト&追加"; const encodedParam = encodeURIComponent(keyword); const fullUrl = baseUrl + encodedParam; console.log(fullUrl); // "https://example.com/search?query=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A%3D%E3%83%86%E3%82%B9%E3%83%88%26%E8%BF%BD%E5%8A%A0"
このように、=
や &
といった特殊文字も安全にエンコードされます。
もし同じ文字列を encodeURI()
でエンコードすると、=
や &
がそのまま残ってしまい、URLとして正しく動作しない場合があります。
URLのクエリパラメータ部分を生成・追加するときには、encodeURIComponent()
が推奨されると覚えておくと役立ちます。
decodeURI
decodeURI()
は、encodeURI()
でエンコードされた文字列を元に戻す(デコードする)ためのメソッドです。
例えば、URL全体をエンコードした後で表示用に戻したいときなどに使われます。
const encodedUrl = "https://example.com/search?query=%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A"; const decodedUrl = decodeURI(encodedUrl); console.log(decodedUrl); // "https://example.com/search?query=あいうえお"
ただし、encodeURIComponent()
でエンコードされた文字列の一部を戻せないケースもあります。
そのため、ペアで使う場合は encodeURI()
と decodeURI()
を組み合わせ、コンポーネント単体の操作には encodeURIComponent()
と decodeURIComponent()
を組み合わせるのが自然な流れです。
decodeURIComponent
decodeURIComponent()
は、encodeURIComponent()
でエンコードされた文字列を復元するメソッドです。
クエリパラメータなどの一部を再利用するときに便利です。
const encodedParam = "%E3%81%82%E3%81%84%E3%81%86%E3%81%88%E3%81%8A%3D%E3%83%86%E3%82%B9%E3%83%88%26%E8%BF%BD%E5%8A%A0"; const decodedParam = decodeURIComponent(encodedParam); console.log(decodedParam); // "あいうえお=テスト&追加"
このように元の文字列に戻すことができます。
URLを生成する際と読み取る際、それぞれでセットのメソッドを使い分けると作業効率が良いです。
特殊文字とエンコードの仕組み
URLエンコードの仕組みを理解するためには、特殊文字がどのように扱われるかを知っておくと便利です。
URLエンコードでは、ASCIIコードに基づいて16進数表記へ変換されます。
例えば、スペースは「%20」、ハイフンは「-」がそのまま残る場合もありますが、文字によっては「%2D」に変換されることもあります。
ここで混乱しがちなのが、+
記号をスペースとして扱う場合があることです。
アプリケーションによっては、スペースを「%20」ではなく「+」で表現するケースがあります。
しかしJavaScriptの encodeURIComponent()
はスペースを「%20」に変換するため、状況によっては「+」への変換を期待していたプログラム側と不整合が起こるかもしれません。
また、全角文字 (日本語など) が含まれる場合は、さらに複数の16進数の組み合わせになります。
例として「あ」という文字は「%E3%81%82」と複数バイトにわたってエンコードされます。
これは日本語がUTF-8などのマルチバイト文字コードを使用しているためです。
こうした内部の処理を細かくすべて暗記する必要はありませんが、「日本語や特殊文字は%xxの形式でエンコードされる」という点を意識しておくと、デバッグなどで役立つでしょう。
特殊文字が思ったとおりにエンコードされない場合、文字コードの設定やエンコード方法を再確認してみるのがおすすめです。
実務で役立つURLエンコードの活用シーン
WEBフォームからのデータ送信
ユーザーが入力したテキストをGETリクエストでサーバーに送る場面では、文字列のURLエンコードが重要です。
例えば、検索フォームから検索キーワードを送信するときに、そのままURLに日本語を含めると文字化けする可能性があります。
そのため、サーバー側が正しく受け取れるように encodeURIComponent()
でクエリパラメータを安全に組み立てることがよく行われます。
また、フォームの送信方法がGETかPOSTかによって実際の送信データの形が変わることもありますが、GETの場合はURLに直接データが付加されるため、とくにエンコードが必要になりやすいです。
クエリパラメータの生成
APIにアクセスするときなど、URLの末尾に ?key=value
のようなクエリパラメータを付けるケースはよくあります。
たとえば、天気情報を取得するAPIで、地名をクエリパラメータに指定したい場合は encodeURIComponent()
を使いましょう。
function buildWeatherApiUrl(cityName) { const baseUrl = "https://api.example.com/weather?"; const param = "city=" + encodeURIComponent(cityName); return baseUrl + param; } const city = "東京"; const url = buildWeatherApiUrl(city); console.log(url); // "https://api.example.com/weather?city=%E6%9D%B1%E4%BA%AC"
このようにすることで、特殊文字(日本語)が含まれていてもURLとして問題なく利用できます。
もし encodeURI()
を使っていた場合、=
や ?
の扱いに差が出たり、エラーに繋がる場合があるので注意です。
APIリクエストでの活用
フロントエンドからサーバーサイドへAPIリクエストを送る際、パラメータをJSONとして送るのか、クエリに含めるのかによってエンコードの必要性が変わります。
クエリパラメータとして追加する場合、英字以外が含まれると正しくデータを送れないケースがあります。
たとえばユーザー名やパスワードに日本語を含むようなケースです。
誤って encodeURI()
を使うと、一部の特殊文字がエンコードされずに残り、サーバー側でパースできないことがあります。
そういったトラブルを避けるためにも、クエリ用の文字列は encodeURIComponent()
で安全に変換してからリクエストを送るのがよくあるパターンです。
URLエンコード関連の注意点とトラブルシューティング
文字化け
一番やっかいなのは文字化けでしょう。
URLエンコードの仕組みを誤解していると、日本語などのマルチバイト文字がうまく変換されず、サーバー側が「%E3%81%82」のまま文字として認識してしまうことがあります。
また、サーバーが受け取った文字列を正しくデコードできない設定になっている場合にも、文字化けが生じるかもしれません。
まずはフロントエンドで encodeURIComponent()
などを使い、正しい形でエンコードしているかを確認しましょう。
そのうえで、サーバー側が受け取ったデータをきちんとURLデコードしているか、文字コード設定が一致しているかもチェックする必要があります。
2重エンコード
2重エンコードとは、本来1度だけエンコードすれば十分な文字列に対して重ねてエンコードを行ってしまうことです。
例えば、すでに「%E3%81%82」の形式にエンコードされた文字列を再度 encodeURIComponent()
に通すと、「%25E3%2581%2582」のようにさらに複雑な形になってしまいます。
この状態になると、サーバー側でデコードしても元の文字列に戻せず、エラーや文字化けが起こります。
2重エンコードを防ぐためには、どのタイミングで何をエンコードしているかを明確にしておくことが大切です。
自分でコードを書く場合は意識しやすいかもしれませんが、外部ライブラリやフレームワークを使う場合、既に内部でエンコードを行っている可能性もあるので、念のため仕様を確認すると良いでしょう。
知らないと困る特例
URLエンコードには「これは例外として扱われる」というケースが存在します。
例えば、RFC規格上では「~(チルダ)」をエンコードするかどうかなど、細かい部分で異なることがあります。
JavaScriptの encodeURIComponent()
はチルダをエンコードしない方針なので、「%7E」にはならずに「~」のまま残ります。
このあたりは、サーバーとの通信仕様やAPIの設計にも影響を受けます。
場合によっては、仕上がったURLが「~」のままでも問題ないこともあれば、「%7E」にしないと弾かれるケースもあるかもしれません。
トラブルに遭遇したときは、規格やAPIドキュメントを再確認するのが早道です。
コード例
最後に、ある程度まとめたコード例を一つ示します。
これはフロントエンド側で、ユーザーが入力した文字列をクエリパラメータに付与してAPIにアクセスし、そのレスポンスを取得する想定の例です。
/** * ユーザーからの検索キーワードでAPIにアクセスし、結果を表示する */ async function fetchSearchResults(query) { // クエリをエンコード const encodedQuery = encodeURIComponent(query); // URLを組み立て const url = `https://api.example.com/search?keyword=${encodedQuery}`; try { const response = await fetch(url); if (!response.ok) { throw new Error("APIから正常なレスポンスを受け取れませんでした。"); } const data = await response.json(); // 取得結果をコンソールに表示(実務では画面表示に使うケースが多い) console.log(data); } catch (error) { console.error("データ取得に失敗しました:", error); } } // フォームの送信ハンドラーとして利用する例 document.getElementById("searchForm").addEventListener("submit", function (event) { event.preventDefault(); const queryInput = document.getElementById("searchQuery"); const queryValue = queryInput.value; if (queryValue) { fetchSearchResults(queryValue); } });
このコード例では、検索キーワードを encodeURIComponent()
でエンコードし、クエリパラメータとしてサーバーに送っています。
ユーザーが入力した特殊文字が含まれていても、ここでエンコードすることで文字化けや通信エラーを回避しやすい作りになっています。
また、受け取ったデータはユーザーに返すタイミングで自由に処理することが可能です。
まとめ
URLエンコードは、普段のWeb開発で意外と意識されずに使われる技術です。
しかし、文字化けやエラーを回避するにはとても大切な要素といえるでしょう。
JavaScriptには encodeURI()
や encodeURIComponent()
、それらに対応するデコード用メソッドが用意されているので、適切に使い分けるだけで基本的な問題を解決できます。
具体的には次の点を押さえておくと、実務でもスムーズに運用できるはずです。
- URL全体をエンコードしたいなら
encodeURI()
- クエリパラメータをエンコードしたいなら
encodeURIComponent()
- デコードはペアとして
decodeURI()
またはdecodeURIComponent()
を使う
文字化けや2重エンコードといったトラブルも、基礎知識を押さえておけば事前に予防できます。
WebフォームやAPIリクエストなど、実務の場面でも何かの拍子にトラブルが起きた場合、今回ご紹介した仕組みを思い出してみてください。
適切にエンコード処理を取り入れることで、アプリケーションの安定性がぐっと高まるでしょう。