「via Internet」談義

charsetに関する注意書き

(1998年11月30日、β1公開。12月6日、β2公開。12月12日、β3公開。1999年1月9日、β4公開。4月1日、特に直すところが思い付かないので、正規版にしちゃうことにした。)

(W3C XML WGメンバーである村田真氏の要請にこたえる形で書いた文書です。)


/日本語エンコード方式の種類/

日本語エンコード(日本語テキストデータのための符号化形式)の代表は、1998年現在のところ、iso-2022-jp(俗にJISと呼ばれる)、euc-jp(extended unix code)、Shift_JIS(俗にMS漢字コードと呼ばれる)です。

:「俗」はあくまで「俗」であって、正しくないようです。たとえば、厳密にはMS漢字コードはShift_JISの上位互換エンコード方式で、NEC拡張とIBM拡張を含むものだそうです。charset名もwindows31jというものが用意される予定です。)

人によっては、このうちのどれが望ましい符号化方式なのか気になるかもしれません。実際には、3者には優劣の差はなく、単に「それぞれ違うも」のです。喩えるなら、データ圧縮方式にZIP(zip)やLZH(lha)やGZ(gzip)などがあって、どれが一番よいとはいえないのと同じです。

Webでは、この3者のうちのどの形式をもちいても構いません。日本語対応ブラウザであれば、どのコードでも自動判別してきちんと表示してくれるでしょう。

:ただし、e-mailやnetnewsでは、慣例としてiso-2022-jpを使います。普通のメールソフトならば、送る時にiso-2022-jpに自動変換してくれることでしょう。)

:将来的には、Shift_JISはInternetから排除される可能性があります(RFC 2046)。Webでもiso-2022-jpにしておくほうのが無難なようです。)


/chaset指定に関する現状認識/

ひょっとすると、「HTMLファイルで日本語をつかったら、その形式を明示するために、HEAD内にMETA要素としてcharsetを指定したほうがよい」という噂をきいたことがあるかもしれません。charsetとは、先に挙げたiso-2022-jpなどのことです。

<META HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-2022-jp">

他にも、「TITLE要素に日本語を使うならば、それより前の段階で明示的にchasetを指定しなければいけない」という噂もきいているかもしれません。

でも、これらの情報は、微妙に間違っているのです。

charsetは、本来はHTML文書の中で指定するものではなく、サーバがHTTPヘッダに付けるべきものです。HTTPヘッダとは、実際にファイルのデータが送付される前にサーバがクライアントに対して送る情報で、「これから送るデータはこういう種類のものだよ」とクライアントに教えるために使われます。ヘッダ情報が無ければ、サーバ/クライアントは膨大なデータ全体をチェックして内容を判断しなければいけません。それを避けるのは当然でしょう。としてみれば、charset情報がヘッダ情報に含まれるべきなのも当然のことです。

charset情報がなければ、本文に使う文字コードがわかりません。だから、先のように「TITLE要素に日本語を使うのは危ない」という意見がでてきます。しかし、サーバがきちんとcharset情報をHTTPヘッダに付けていれば、(META要素などつけなくとも)TITLE要素で日本語を使ってOKです。

ちなみに、「META要素としてcharsetを明示しよう」といわれている原因は、多くのサーバがHTTPヘッダにcharset情報を出していないからです。そして、META要素のcharset指定は「サーバさん、charset情報をHTTPヘッダに付けてよ」というお願いとして提案・導入されたのです。

でも、現状ではMETA要素はそのようには動作していません。なぜなら、これを可能にするには、サーバは、データ送付前にデータの内容をチェックしなければいけないんです。いかにも無理っぽいですよね。

現状では、META要素によるcharset指定は、ただたんにクライアントがチェックするものになっています。これでは、ほとんど意味がありません。charsetは、HTTPヘッダに提示されなければいけないのです。

(ちなみに、META要素が本来の意図どおりに運用されたとしても、解決できるのは、HTML文書のcharsetだけです。言い換えれば、テキストファイル転送時のcharset情報は解決されません。やっぱり、サーバ側がHTTPヘッダにcharsetを提示しなければ、根本的な解決にはならないのです。)

というわけで、「HTML文書公開者に、META要素でcharsetを指定するように啓蒙する」のは正しくありません。HTTPサーバ管理者に、HTTPヘッダにcharsetを付けるように啓蒙しなければいけません。


/未来に向けて/

サーバ側が実際にcharsetを指定するのは、なかなか困難です。なぜなら、そのサーバ利用者(ここでの「利用者」は、データをputするほうの人)が使っている日本語コードはバラバラかもしれないからです。

方策例をいくつかあげます。(:HTMLファイルのことだけを想定しています。)

  1. そのサーバ管理者が、利用者に特定のコードの利用を強要する。charasetはひとつでよい。
  2. 日本語コードごとに拡張子を使い分けるようにする。html-jis、html-sjis、html-eucなど。chrasetは拡張子にひとつでよい。
  3. サーバがクライアントの要求にこたえる前に、全データのコードを変換してひとつにしてしまう(proxy状態)。charasetはひとつでよい。

どの場合でも、「実際のデータのエンコード形式とcharset情報が一致する」ことが必須です。

すると、HTML文書内の「META要素によるcharset指定」は無用であるばかりか、かえって有害です。なぜなら、サーバが行ったコード調整によって指定が食い違う可能性があるからです。たとえば、「サーバが送り出す段階ではデータはis-2022-jpなのに、METAにはShift_JISと書いてある」という食い違いが起こりえます。こういうデータを受け取ったクライアントは、データをうまく表示できません。

:もっとも、サーバの処理に関わらず、「現在でも実際の日本語コードとMETAのcharsetが食い違っている」というのは珍しくありません。無能なWYSIWYG-HTMLエディタは、内容を判断せずにiso-2022-jpのcharset(やHTMl3.2のDOCTYPE)を付けていたりするものです。時には、x-euc-jpとかx-sjisといったNetscape社独自拡張の指定を付けているケースもあります。ついでに覚えておいて欲しいのですが、「x」は「extension(独自拡張)」であることの表明です。すなわち、「正式・一般採用のものではない」のです。)

したがって、私は「HTML内部のMETAによるcharset指定は削除する」ことをオススメします。


/関連リンク/


/特記:「.htaccess」をオススメしないわけ/

一部のサーバデーモン(たとえばApache)では、各ディレクトリごとに、「拡張子とMIMEタイプ、およびそれにまつわる各種ヘッダ情報」を、そのディレクトリの所有者が設定できるようになっています。すなわち、これを使えば、個人個人でcharset対策が可能です。

(なお、一般的には、設定ファイル「.htaccess」として情報を記述します。したがって、以降は「.htaccess」(による設定)と呼称します。)

しかし、「.htaccess」による方法は、実際には望ましい解決だとは思いません。なぜなら、それは「一般ユーザが行うには難しい」からです。

私は、charsetヘッダなどはインフラストラクチャーに含まれると思います。その整備はサーバ管理者の仕事であって、一般ユーザの仕事ではないと思います。サーバ管理者が明示的に「一般ユーザさん、もうしわけないけど、各自の“.htaccess”でcharsetに対処してください。」とお願いしているならともかく、そうでない限りはサーバ管理者がcharset問題を解決するべきだと思います。

(もっとも、本当にサーバ管理者が「一般ユーザが自分で整備して」と言い出したら、おかしなことでしょうね。大学の教員や学生むけサービスであれば、一般ユーザにもボランティア作業を求めても構わないかもしれません。しかし、商用プロバイダであれば、一般ユーザは「お金を取ってるんだから、利用者にそこまで求めるな」といわれるでしょう。−−起こってもいないことをここまで想像するとは、私もけっこう病気ですね。)






ご意見ご要望及び苦情はE-MAILにて

e-mail to : jy3k-sm#!#!asahi-net.or.jp