エンコード

エンコードについて

URLエンコードについて

JavaScriptでは文字列をエンコードする命令が3つ用意されています。

1つは古いブラウザでも利用できるescape()メソッド、次がencodeURI()、そして最後がencodeURIComponent()です。

# 関数 説明
1 escape Safariではうまく日本語が処理できないことがあります。
2 encodeURI Internet Explorerでは5.5以降でのみ利用できます。
3 encodeURIComponent Internet Explorerでは5.5以降でのみ利用できます。

encodeURI()とencodeURIComponent()の違い

「#$&+,/:;=?@」をエンコードするかどうかの違いがあります。

encodeURI()はこれらの文字をエンコードしませんが、encodeURIComponent()では下表のようにエンコードします。

関数 # $ & + , / : ; = ? @
encodeURI() # $ & + , / : ; = ? @
encodeURIComponent() %23 %24 %26 %2B %2C %2F %3A %3B %3D %3F %40

比較表

すべての関数でエンコードされない文字は、*-.@_ 0から9 AからZ aからz

escape()でエンコードされない記号は、*+-./@_の7文字(水色の背景色)

encodeURI()でエンコードされずにencodeURIComponent()でエンコードされる記号は、黄色の背景色の箇所。その反対のパターンは存在しない。

  半角スペース ! " # $ % & ' ( ) * + , - . /
escape %20 %21 %22 %23 %24 %25 %26 %27 %28 %29 * + %2C - . /
encodeURI %20 ! %22 # $ %25 & ' ( ) * + , - . /
encodeURI
Componet
%20 ! %22 %23 %24 %25 %26 ' ( ) * %2B %2C - . %2F
  0 1 2 3 4 5 6 7 8 9 : ; < = > ?
escape 0 1 2 3 4 5 6 7 8 9 %3A %3B %3C %3D %3E %3F
encodeURI 0 1 2 3 4 5 6 7 8 9 : ; %3C = %3E ?
encodeURI
Componet
0 1 2 3 4 5 6 7 8 9 %3A %3B %3C %3D %3E %3F
  A B C D E F G H I J K L M N O
escape @ A B C D E F G H I J K L M N O
encodeURI @ A B C D E F G H I J K L M N O
encodeURI
Componet
%40 A B C D E F G H I J K L M N O
  P Q R S T U V W X Y Z [ \ ] ^ _
escape P Q R S T U V W X Y Z %5B %5C %5D %5E _
encodeURI P Q R S T U V W X Y Z %5B %5C %5D %5E _
encodeURI
Componet
P Q R S T U V W X Y Z %5B %5C %5D %5E _
  ` a b c d e f g h i j k l m n o
escape %60 a b c d e f g h i j k l m n o
encodeURI %60 a b c d e f g h i j k l m n o
encodeURI
Componet
%60 a b c d e f g h i j k l m n o
  p q r s t u v w x y z { | } ~ DL
escape p q r s t u v w x y z %7B %7C %7D %7E  
encodeURI p q r s t u v w x y z %7B %7C %7D %7E  
encodeURI
Componet
p q r s t u v w x y z %7B %7C %7D %7E  

エンコード

入力
escape
encodeURI
encodeURIComponent



デコード

入力
unescape
decodeURI
decodeURIComponent

入力した文字をエンコードしてみる


escape関数の問題点

歴史的な経緯もあり、escape、unescapeメソッドがURI文字列をハンドリングするために使われてきましたが、その動作はブラウザごとに異なるため現在は推奨されていません。

IEでは文字列をUCS2の16進表示にした上で「%u」をプレフィクスとして付けた文字列が生成され、これはunescape()ではデコードできますが、decodeURI(decodeURIComponent)ではデコードできません。

そもそもCookieに格納する文字列は、UTF-8に変換された上でURIエンコーディングされることになっています。これをエンコード、デコードするJavaScriptのメソッドはencodeURI(またはencodeURIComponent)、decodeURI(またはdecodeURIComponent)です。

逆にencodeURI(encodeURIComponent)を使って正しくURIエンコーディングされた文字列は、unescapeではデコードできません。

要するにescape、unescapeメソッドは使うべきではありません。

encodeURI(encodeURIComponent)の注意点

JavaScriptのencodeURI(encodeURIComponent)はHTMLソースの文字コードに依らずUTF-8でエンコードします。decodeURI(decodeURIComponet)でデコードする際にもUTF-8でエンコードされていることを前提としています。

デコードした文字列を表示する場合、HTMLソースの文字コードに自動的に変更してくれるので文字化けは発生しません。要するにHTML内で閉じている場合は特に問題は発生しません。

ところが、エンコードした文字列をサーバーに渡してデコードする場合や、反対にサーバーで生成した文字列をエンコードしてJavaScriptに渡してデコードする場合には注意が必要です。

サーバー(PHP)のURLエンコードは文字コードにより異なります。すなわち、JavaScriptのようにUTF-8を前提としているわけではないのです。

従って、クライアントから送信された文字列の文字コードは何かということを意識してデコードしないと文字化けを起こしてしまいます。

PHPでは、mb_convert_encoding()関数で文字コードを変更することができます。encodeURI()でエンコードする前に文字列を明示的にUTF-8に変更してからエンコードすることでJavaScriptと同じ方式でエンコードされることが保証されます。

GETメソッドについて

encodeURI(encodeURIComponet)によりエンコードする際の文字コードはUTF-8でしたが、フォームをGETメソッドで送信する際に自動でエンコードされる時には、HTMLソースの文字コードが適用されるようです。(これはIE8の場合です。ブラウザによって実装が異なるかもしれません。)

下記は、フォームのvalueという名前のテキストボックスに「日本語」と入力して送信したときにどのようにエンコードされるかを示したものです。ページの文字コードによって送信クエリーが異なることが分かります。

ページの文字コード 送信クエリー
UTF-8 value=%E6%97%A5%E6%9C%AC%E8%AA%9E
EUC-JP value=%C6%FC%CB%DC%B8%EC
SHIFT_JIS value=%93%FA%96%7B%8C%EA

サーバー側では送信クエリーの文字コードを知っている必要があります。多くの場合は自動判定でも認識できるようですが、本来は明示的に文字コードを指定してデコードすべきです。

送信クエリーにはエンコードの文字コードを示すものは送信されません。これは歴史的な経緯によるものだと思いますが、明らかに仕様の不備だと思います。例えば、Googleの検索クエリーでは「IE」や「OE」というパラメータによって文字コードを明示的に示しています。これに習って文字コードを一緒にパラメータで渡すようにするのは良い習慣だと思います。

 

↑このページの先頭へ