●encodeURI関数とは?
今回は、JavaScriptのencodeURI関数について一緒に学んでいきましょう。
URLをエンコードする際に欠かせないこの関数、一体どんなものなのでしょうか?
encodeURI関数は、文字通りURLをエンコードするための関数です。
URLには、特殊文字や非ASCII文字が含まれることがありますよね。そのままURLに使用すると、思わぬエラーを引き起こす可能性があります。
そこで登場するのがencodeURI関数なのです。
○encodeURIとencodeURIComponentの違い
ここで、よく似た関数であるencodeURIComponentとの違いを理解しておくことが大切です。
encodeURIは、URI全体をエンコードするのに対し、encodeURIComponentは、URI内の個々のコンポーネントをエンコードします。
つまり、encodeURIComponentの方がより厳密にエンコードを行うのです。
例えば、次のようなURLがあるとしましょう。
この場合、encodeURIを使うと、次のようにエンコードされます。
一方、encodeURIComponentを使うと、次のようになります。
状況に応じて適切な関数を選ぶことが重要ですね。
○なぜencodeURI関数が必要なのか
さて、なぜそもそもencodeURI関数が必要なのでしょうか?
URLに特殊文字や非ASCII文字が含まれていると、どのような問題が起こるのでしょう?
実は、これらの文字をそのままURLに使用すると、ブラウザがURLを正しく解釈できなくなる可能性があるのです。
その結果、意図したページにアクセスできなかったり、セキュリティ上の問題を引き起こしたりする恐れがあります。
例えば、次のようなURLがあるとします。
このURLには、スペースと&記号が含まれています。
この文字をエンコードしないで使用すると、ブラウザは次のように解釈してしまうかもしれません。
本来1つのパラメータであったものが、2つに分割されてしまったのです。
これでは、意図した検索結果を得ることができません。
こういったトラブルを避けるために、encodeURI関数を使ってURLをエンコードする必要があるのです。
○サンプルコード1:基本的な使い方
それでは、encodeURI関数の基本的な使い方を見ていきましょう。
次のようなURLがあるとします。
このURLをエンコードするには、次のようにencodeURI関数を使います。
実行結果は次のようになります。
スペースが%20にエンコードされていますね。
これで、URLを安全に使用することができます。
encodeURI関数を使うことで、URLに含まれる特殊文字や非ASCII文字を適切にエンコードし、URLを正しく機能させることができます。
●encodeURI関数の使い方
前回は、encodeURI関数の基本的な使い方を見てきました。
URLに含まれる特殊文字や非ASCII文字を適切にエンコードし、URLを正しく機能させることができるのでしたね。
でも、具体的にはどのような文字をエンコードするのでしょうか?
文字によってエンコードの方法が異なるのでしょうか? ちょっとややこしいですが、一緒に見ていきましょう。
○サンプルコード2:特殊文字のエンコード
まずは、特殊文字のエンコードから見ていきましょう。
URLには、&、=、?、%、#、+、;、:、,、/、”、’、<、>、[、]、{、}、|、\、^、`、(、)などの特殊文字が使用されることがあります。
この文字は、そのままURLに使用するとトラブルの原因になる可能性があるので、エンコードする必要があります。
例えば、次のようなURLがあるとします。
このURLをエンコードするには、次のようにencodeURI関数を使います。
実行結果は次のようになります。
ん? 変化がないように見えますね。
実は、encodeURI関数は、&、=、?、:、/、;、#、[、]などの一部の特殊文字をエンコードしないのです。
これらの文字は、URLの構造を作る上で重要な役割を果たすため、エンコードしてしまうとかえってURLが機能しなくなってしまうのです。
じゃあ、これらの文字はどうやってエンコードするのでしょうか?
その答えは、ズバリencodeURIComponent関数です。encodeURIComponent関数は、encodeURI関数よりも厳密にエンコードを行い、&、=、?、:、/、;、#、[、]などの文字もエンコードします。
先ほどの例で、encodeURIComponent関数を使ってみましょう。
実行結果は次のようになります。
&、=、?、:、/などの文字がエンコードされていますね。
ただ、この結果をそのままURLとして使用することはできません。
encodeURIComponent関数は、URI全体ではなく、URI内の個々のコンポーネントをエンコードするために使用するのです。
○サンプルコード3:非ASCII文字のエンコード
続いて、非ASCII文字のエンコードを見ていきましょう。
非ASCII文字とは、英数字や一部の記号以外の文字のことを指します。
日本語や中国語、ハングルなどの多言語の文字もこれに含まれます。
例えば、次のようなURLがあるとします。
このURLをエンコードするには、次のようにencodeURI関数を使います。
実行結果は次のようになります。
非ASCII文字である「こんにちは世界」が、%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF%E4%B8%96%E7%95%8Cという形式でエンコードされていますね。
これは、パーセントエンコーディングと呼ばれる方式で、非ASCII文字を%に続く16進数で表現します。
○サンプルコード4:パーセントエンコーディング
パーセントエンコーディングについて、もう少し詳しく見ていきましょう。
パーセントエンコーディングでは、文字をUTF-8でバイト表現したものを16進数で表し、その前に%を付けます。
例えば、「こ」という文字は、UTF-8では0xE3 0x81 0x93というバイト列で表されます。これを16進数で表すと、%E3%81%93となるのです。
encodeURI関数やencodeURIComponent関数は、内部的にこのパーセントエンコーディングを行っています。
ですから、日本語や中国語などの非ASCII文字を含むURLをエンコードする際は、これらの関数を使えば自動的にパーセントエンコーディングされるのです。
ちなみに、パーセントエンコーディングされた文字列は、decodeURI関数やdecodeURIComponent関数を使ってデコードすることができます。
デコードについては、次のサンプルコードで詳しく見ていきましょう。
○サンプルコード5:デコードの方法
エンコードされたURLを元の文字列に戻すには、decodeURI関数やdecodeURIComponent関数を使います。
先ほどのサンプルコードで、エンコードされたURLをデコードしてみましょう。
実行結果は次のようになります。
パーセントエンコーディングされた文字列が、元の「こんにちは世界」に戻っていますね。
encodeURIComponent関数でエンコードされた文字列は、decodeURIComponent関数を使ってデコードします。
実行結果は次のようになります。
このように、エンコードとデコードは、encodeURI関数とdecodeURI関数、encodeURIComponent関数とdecodeURIComponent関数がペアになっています。
エンコードされた文字列は、対応するデコード関数を使えば元の文字列に戻すことができるのです。
●よくあるエラーと対処法
encodeURI関数を使っていると、時々エラーに遭遇することがあります。
まずは、一緒にエラーの原因と対処法を見ていきましょう。
○URIError: malformed URI sequence
「URIError: malformed URI sequence」というエラーメッセージを見たことがあるでしょうか?
このエラーは、不正な形式のURIを扱おうとした時に発生します。
例えば、次のようなコードを実行すると、このエラーが発生します。
実行結果は次のようになります。
エラーメッセージから、URIの形式が不正であることがわかりますね。
この例では、クエリパラメータ内にスペースが含まれています。
スペースは、URIでは%20とエンコードする必要があるのです。
このエラーを解決するには、次のようにencodeURIComponent関数を使ってクエリパラメータをエンコードします。
実行結果は次のようになります。
クエリパラメータ部分がencodeURIComponent関数でエンコードされ、正しい形式のURIになりましたね。
○文字化けが発生する
encodeURI関数を使ってURLをエンコードした時に、文字化けが発生することがあります。
文字化けが発生すると、URLが正しく機能しなくなってしまいます。
文字化けの原因は、主に次の2つです。
- 文字コードが適切でない
- 不適切な文字が含まれている
文字コードが適切でない場合、次のようにcharsetパラメータを指定することで解決できます。
不適切な文字が含まれている場合は、その文字を取り除くか、別の文字に置き換える必要があります。
例えば、半角カナは文字化けの原因になることがあるので、全角カナに置き換えるのが良いでしょう。
○エンコードされない文字がある
encodeURI関数は、&、=、?、:、/、;、#、[、]などの一部の特殊文字をエンコードしません。
上述のような文字は、URLの構造を作る上で重要な役割を果たすため、エンコードしてしまうとかえってURLが機能しなくなってしまうのです。
しかし、これらの文字をエンコードしたい場合もあるでしょう。
そんな時は、encodeURIComponent関数を使います。encodeURIComponent関数は、encodeURI関数よりも厳密にエンコードを行い、&、=、?、:、/、;、#、[、]などの文字もエンコードします。
例えば、次のようなコードを実行すると、&記号がエンコードされずに残ってしまいます。
実行結果は次のようになります。
この場合は、encodeURIComponent関数を使って、クエリパラメータ部分をエンコードします。
実行結果は次のようになります。
&記号が%26にエンコードされていますね。
エラーに遭遇した時は、まずエラーメッセージをよく読むことが大切です。
エラーメッセージには、エラーの原因やヒントが書かれていることが多いのです。
そして、エラーの原因を特定したら、適切な方法で対処しましょう。
●encodeURI関数の応用例
さて、ここまでencodeURI関数の基本的な使い方やエラー対処法について解説してきました。
基本を押さえることは大切ですが、実際のプロジェクトでは、もっと複雑なURLを扱うこともあるでしょう。
そんな時、encodeURI関数はどのように活用できるのでしょうか?
○サンプルコード6:複数のパラメータを持つURL
Webアプリケーションを開発していると、複数のパラメータを持つURLを扱う場面に遭遇することがあります。
例えば、検索機能を実装する際、検索キーワードやカテゴリ、ソート順などの情報をURLに含めることがよくあります。
こんな感じのURLを想像してみてください。
このURLには、qパラメータ(検索キーワード)、categoryパラメータ(カテゴリ)、sortパラメータ(ソート順)の3つのパラメータが含まれています。
こういったURLをエンコードする際は、次のようにencodeURIComponent関数を使ってパラメータ部分をエンコードします。
実行結果は次のようになります。
ここでは、Object.entriesメソッドを使ってパラメータオブジェクトからキーと値のペアの配列を取得し、mapメソッドを使ってそれぞれのペアをエンコードした文字列に変換しています。
最後に、joinメソッドを使ってそれらの文字列を&で結合し、URLに付加しています。
このように、encodeURIComponent関数を使えば、複数のパラメータを持つURLも簡単にエンコードできるのです。
○サンプルコード7:ユーザー入力値のエンコード
Webアプリケーションでは、ユーザーからの入力値を受け取ることがよくあります。
例えば、フォームに入力された値をサーバーに送信する際、その値をURLの一部として使用することがあります。
しかし、ユーザーの入力値には、URLに使用できない文字が含まれている可能性があります。
そのため、ユーザーの入力値をエンコードしてからURLに含める必要があるのです。
次のコードは、ユーザーの入力値をエンコードしてURLに含める例です。
このコードでは、フォームの送信イベントをリッスンし、送信ボタンがクリックされた時の処理を定義しています。
フォームが送信された時、次の処理が行われます。
- event.preventDefault()を呼び出して、フォームの標準の送信動作をキャンセルします。
- nameフィールドの値を取得します。
- encodeURIComponent関数を使ってnameの値をエンコードします。
- エンコードされたnameの値を含むURLを生成します。
- 生成されたURLをコンソールに出力します。
例えば、フォームにJohn Doeと入力してSubmitボタンをクリックすると、次のようなURLがコンソールに出力されます。
このように、ユーザーの入力値をエンコードしてからURLに含めることで、ユーザーの入力値に含まれる特殊文字を適切に扱うことができるのです。
○サンプルコード8:Ajax通信でのURL指定
Ajaxを使ってサーバーとの通信を行う際、リクエストURLを指定する必要があります。
その際、URLに含めるパラメータをエンコードすることが重要です。
次のコードは、jQueryを使ってAjax通信を行う例です。
ここでは、$.paramメソッドを使ってパラメータオブジェクトをエンコードされたクエリ文字列に変換しています。
$.paramメソッドは内部的にencodeURIComponent関数を使ってエンコーディングを行っています。
このコードを実行すると、次のようなリクエストURLが生成されます。
このように、Ajax通信でURLを指定する際も、パラメータをエンコードすることが大切です。
○サンプルコード9:動的なURL生成
JavaScriptを使って動的にURLを生成する際も、encodeURI関数やencodeURIComponent関数を活用することができます。
例えば、ユーザーのアクション(クリックやフォーム入力など)に基づいてURLを生成し、そのURLにリダイレクトするような場合です。
次のコードは、ユーザーのアクションに基づいてURLを生成し、そのURLにリダイレクトする例です。
このコードでは、ボタンのクリックイベントをリッスンし、クリックされた時の処理を定義しています。
ボタンがクリックされた時、次の処理が行われます。
- baseURLとparamsオブジェクトを定義します。
- Object.entriesメソッドとmapメソッドを使ってparamsオブジェクトをエンコードされたクエリ文字列に変換します。
- baseURLとクエリ文字列を結合して、完全なURLを生成します。
- window.location.hrefにURLを代入して、そのURLにリダイレクトします。
このコードを実行し、ボタンをクリックすると、次のURLにリダイレクトされます。
このように、動的にURLを生成する際も、encodeURI関数やencodeURIComponent関数を使ってURLをエンコードすることが大切です。
●encodeURI関数を使う際の注意点
encodeURI関数は、URLをエンコードする上で非常に便利な関数ですが、使い方を誤ると思わぬ問題を引き起こす可能性があります。
ここでは、encodeURI関数を使う際の注意点について、サンプルコードを交えながら見ていきましょう。
○サンプルコード10:過剰なエンコーディングの防止
encodeURI関数を使ってURLをエンコードする際、エンコード済みの文字列に対して再度encodeURI関数を適用すると、過剰なエンコーディングが発生することがあります。
例えば、次のようなコードを実行すると、過剰なエンコーディングが発生します。
実行結果は次のようになります。
元のURLでは、スペースが%20にエンコードされていましたが、encodeURI関数を適用することで、%25に再エンコードされてしまいました。
過剰なエンコーディングを防ぐには、エンコード済みの文字列に対してencodeURI関数を適用しないようにします。
代わりに、エンコードが必要な部分だけを切り出し、encodeURIComponent関数を使ってエンコードします。
実行結果は次のようになります。
このように、エンコードが必要な部分だけを切り出してエンコードすることで、過剰なエンコーディングを防ぐことができます。
○サンプルコード11:httpプロトコルの扱い
encodeURI関数は、httpプロトコルを含むURLに対しても適用することができます。
しかし、httpプロトコルを含むURLをエンコードすると、予期せぬ問題が発生する可能性があります。
例えば、次のようなコードを実行すると、httpプロトコルがエンコードされてしまいます。
実行結果は次のようになります。
httpプロトコルが%3A(コロン)にエンコードされてしまいました。
これでは、URLとして機能しません。
httpプロトコルを含むURLをエンコードする際は、httpプロトコル部分を切り出し、残りの部分だけをエンコードするのが良いでしょう。
実行結果は次のようになります。
httpプロトコル部分は、エンコードされずに残り、残りの部分だけがエンコードされました。
このように、httpプロトコルを含むURLをエンコードする際は、httpプロトコル部分を切り出してから残りの部分をエンコードするのが安全です。
○サンプルコード12:バックスラッシュの扱い
encodeURI関数は、バックスラッシュ(\)をエンコードしません。
これは、バックスラッシュがエスケープシーケンスの一部として使用されることが多いためです。
しかし、バックスラッシュを含むURLをエンコードする際は、注意が必要です。
例えば、次のようなコードを実行すると、バックスラッシュがエンコードされずに残ってしまいます。
実行結果は次のようになります。
バックスラッシュがエンコードされずに残ってしまいました。
バックスラッシュを含むURLをエンコードする際は、バックスラッシュを別の文字に置き換えるか、encodeURIComponent関数を使ってエンコードするのが良いでしょう。
実行結果は次のようになります。
バックスラッシュがスラッシュ(/)に置き換えられ、正しくエンコードされました。
このように、バックスラッシュを含むURLをエンコードする際は、バックスラッシュの扱いに注意が必要です。
まとめ
encodeURI関数は、JavaScriptでURLをエンコードする際に欠かせない関数です。
特殊文字や非ASCII文字を適切にエンコードし、URLを安全に扱うことができます。
基本的な使い方から、エラー対処法、応用例、注意点まで、様々な側面から解説してきました。
URLエンコードはWebアプリケーション開発に必須の技術であり、encodeURI関数を使いこなすことで、より安全で信頼性の高いアプリケーションを開発することができるでしょう。
今回学んだ知識を活かして、JavaScriptでのURLエンコードに自信を持って取り組んでいきましょう。