文字符号化方法を記したMETA宣言の地位を低下させようと企む理由とエトセトラ

企む理由

Webのテキスト系リソースは、HTMLファイルだけではありません。単なるプレーンテキストはMETA情報を持つことが出来ませんし、外部スタイルシートなどHTMLファイルと連動して「ページ」形成のために働くテキストファイルの種類と重要性は近頃非常に増しています。

HTTP 1.1 仕様 section 3.7.1 はテキスト系リソースの伝送に際して、ISO-8859-1 以外の文字符号化方法で符号化されたファイルを送信する場合はHTTP応答ヘッダに適切なcharsetパラメタを与えることを必須としています。更にまた同仕様は、HTTP 1.0 段階のソフトウエアの中にはcharsetパラメタが欠けた状態のリソースを誤って「文字符号化方法については適宜判断せよ」という意味に捉えるものもあるので ISO-8859-1 であっても明示せよ、と注意を促しています。

恐らく以上のような背景を前提に、HTML 4.0 仕様 5.2.2 は、文字符号化方法の識別に関して次の優先順位によって処理することを求めています。

  1. HTTP応答ヘッダのcharsetパラメタ
  2. ソース自身の符号化方法を示すMETA宣言の情報
  3. A要素やFORM要素などに記されている符号化方法に関する情報

これは、「上位に記した情報が不在だったら下位の情報を利用する」ということだけを述べているのではなく、「上位の情報と下位の情報が食い違ったら上位の情報に従う」ことをも求めている筈です。

近い将来に登場するHTML 5.0(とでも呼ばれるであろうもの)はXML規定に則るものになることが告示されており、またtext/xmlメディアタイプを規定するRFC2376が「HTTP応答ヘッダにcharsetパラメタが欠けていた場合には(例えソース中に文字符号化方法に関する情報があっても無視して)US-ASCIIとして取り扱え」と定めているため、今のうちからcharsetパラメタに慣れておかないと、ちょっと困りそうです。

そんなわけで、HTMLファイルを作ったり送ったりする際にも、METAではなくHTTP応答ヘッダのcharsetパラメタを重要視するよう各方面に求めようと思うのです。


文字符号化方法を明示する必要がどこにあるのか

電子テキストを構成する文字列は、何らかの文字符号化方法による符号化を経てバイト列として記録・保存・伝送され、またバイト列は復号によって文字列へと変換されます。

究極的には「あるかないか」「0か1か」といったものとして表されるコンピュータの情報単位=1ビットが8つ集まったものを「(8ビットの)1バイト」と呼び、便宜上それを16進数2桁で「00」「99」「AF」等のように表すことが多いようで、2バイトで1つの文字を表すような文字符号化方法によって得られるバイト列は「9E74」などという文字コードとして記述されたりします。

アプリケーション内部で「内部コード」を用いて作成編集した電子テキストを、ファイルとして記録したり他の機器と通信したりするためには「外部符号化」が行われます。外部符号化に利用される文字符号化方法は、一般的に、ASCII文字をASCIIコードと同じバイトコードで表した上、(1) 追加的に利用する文字集合を切り替えることを「エスケープシーケンス」を用いて示すか、(2) ASCII文字が使わない8ビット目の利用によってASCII以外の文字集合の利用を暗示するか、という大きな枠組みに沿っています。

ISO-2022-JPは(1)に属し、Shift_JISは(2)に属しています(また、ISO-8859シリーズも(2)に属していると考えられます)。EUC-JPは(1)として使うことも(2)として使うこともできるのですが、ほとんどの場合(2)として使われるようです。(2)に属する文字符号化方法の何が使われるのか不明な場合、8ビット目が利用されることの意味が衝突してしまいますので、識別が困難になります。

ここに例えば「B2BE」というバイト列があるとして、これをShift_JISによって復号すると半角カタカナの「アセ」という文字列になるけれどもEUC-JPで復号すると漢字の「仮」という文字になり更にISO-8859-1で復号すると「±¾(プラスマイナス四分の三)」になるのだけれども何で符号化したかは当該バイト列だけからは判らない、という状況になっています。ここから、不特定多数の間で電子テキストを共有するには、どうにかして文字符号化方法を別途伝える必要があると判ります。

人間が読むために「ページ」にアクセスした場合には、ある程度の長さのあるテキストが対象である場合は文字化けのパターンなどから正しい符号化方法を判断できる場合もありますが、機械的に裏方処理されるようなデータの場合、人間の判断が介在する余地がありませんから、文字符号化方法の情報が不在だと不都合が生じるでしょう。

常にUS-ASCIIのみで用件を済ませるようにしておけば最も安全でしょうけれど、それは余りにかったるいので、「今後の安全と便利」を掴み取るために考え出された HTTP 1.1 仕様の規定を守ってcharsetパラメタを利用するための方策を考えると共に、一応現在の安全を確保するための情報を記しておきます。

Shift_JISとEUC-JPの自動判定を助ける方法

HTMLのソースを眺めていると、先頭の方に「<-- 美乳 -->」「<-- 譚 -->」などの意味不明なコメントが挿入されていることがあります。これらのコメントは、Shift_JISとEUC-JPの仕様上、8ビット×2バイト(10進数で言うと256×256)のコード空間において重複しない部分があることを利用して両者を識別させようとするものです。

8ビット×2バイトのコード空間に占めるShift_JISの符号集合とEUC-JPの符号集合の位置

大雑把に言うと、JIS X 0208の区点コードが93点と94点の値を持つ文字をEUC-JPで符号化した場合、そのコードはShift_JISが利用しないコードとなる一方、Shift_JISで符号化した場合にもEUC-JPが利用しないコードとなります。「美乳」や「譚」の場合、句点コードで表すと「40区94点、38区93点」「75区93点」であり、Shift_JISで符号化した場合はEUC-JPが利用しないコード、EUC-JPで符号化した場合にはShiftJISが利用しないコードになる文字なので、両者のどちらで符号化する場合でも識別子として役立つ文字であると言えます。また例えば「入口」という熟語の句点コードは「38区94点、24区93点」なので、ソースの先頭の方に記しておくのに「美乳」や「譚」よりは適した文字列でしょう。

META宣言のhttp-equiv属性によって文字符号化方法を明示するという方法がブラウザに実装されはじめた頃のNetscape Navigatorが利用していたcharsetパラメタがShift_JISとEUC-JPについてはIANA登録外の符号化方法を表す「x-****」式のものであり、その他のブラウザと古い版のNetscape Navigatorとの間でcharsetパラメタの扱いが変わってしまったため、少なくともShift_JISとEUC-JPの識別に関しては、META宣言よりはコメント中の文字列によって自動判定を助ける方法の方が安全だという意見が根強くあるようです。

本当に上のような安全性・危険性について気にかけるなら、杓子定規な処理をせず、クライアントに応じた処理の振り分けを行い、「コメント」「META」「charsetパラメタ」を使い分けるといいでしょう。

HTTP応答ヘッダにおけるcharsetパラメタを利用できるようにする方法

文字符号化方法の統一

当該サイトで利用してよい文字符号化方法を一種類に限定してしまえば、text系リソースに関するcharsetパラメタは一種類だけを考えればよくなりますから、話は簡単です。全く新しいサイトを立ち上げる場合や、当該サイトにWWW文書を置く人々がごく少ないような場合、また書かれる文書に利用される文字集合がある1つのもので用が足りるというような場合には、最も単純で便利な方法であるかもしれません。もちろん、charsetパラメタを扱えないサーバの場合は問題外ですけれど。

META宣言

WWWで利用されるtext系リソースは、HTMLやXMLなどのように文字符号化方法に関するメタ情報を持てるとは限らないので、HTTP 1.1仕様は当該リソースのデフォルトではない文字符号化方法を用いる場合はHTTP応答ヘッダのcharsetパラメタによってそれを明示するよう求めています。

HTTP 1.0仕様においてもオプション機能としてcharsetパラメタは存在し、NCSAのサーバソフトウエアがその利用手段を実装していたそうです。NCSAサーバはHTMLソース中のMETA宣言のうちhttp-equiv属性の内容をHTTP応答ヘッダに反映させる機能をも持っており、ソース中の「<META http-equiv="Content-Type" content="text/html; charset=ISO-2022-JP">」といったMETA宣言を読み込んで、HTTPヘッダ中のMIMEタイプとcharsetパラメタを記すフィールドに反映させるような設定ができるそうです。

文字符号化方法をMETA宣言でサーバに伝える手法には、「いちいちソースを読み取らなければならないのでえらく時間がかかる」「ASCII文字がASCIIとは異なるコードで符号化された際に完全に無力である」「HTMLでしか利用できない」などの欠点があり、結局は当初の目的通りには機能させられず、現在ではブラウザがローカルHTMLファイルの符号化方法を識別する際に用いられたり、HTTP応答ヘッダ中にcharsetパラメタが存在しない場合の補助情報として用いられたりするものとなっています。

前にも記した通り、text/xmlにおいてはcharsetを示す情報がテキスト中に記してあってもなくても「HTTP応答ヘッダにcharsetパラメタが不在の場合はUS-ASCIIとして処理せよ」と求めていますから、今のうちに別の方法を考えておいた方がよいでしょう。

AddTypeコマンド

CERNサーバやApacheサーバで利用できる「AddType」コマンドは、特定の拡張子とcharsetとの結びつきを明示する機能を持っています。そこで例えば『Creating a multilingual site with the CERN-httpd server』などは「.html」を(デフォルトである)ISO-8859-1で符号化したファイルとして扱い「.html2」という拡張子のファイルをISO-8859-2で符号化したものとしてHTTP応答ヘッダの設定を行うことが可能であると述べています。

書き手の各々が「.htaccess」を利用する場合

「.htaccess」機能を使うと、当該ディレクトリに対してのみ効力を持つようなAddTypeコマンドの設定を行えます。そこで、『charsetパラメタの勧め: HTMLにおける文字符号化スキームの明示方法』などは、この方法を奨めています。

この場合、書き手本人は、自分が作るファイルの文字符号化方法を統一して「.htmlはUTF-8だ」という設定を行うこともできますし、自分が使う複数の文字符号化方法と拡張子との使い分けを設定することもできます。

サーバの管理者がルートで設定する場合

サーバソフトウエアに元々機能が無いとか、何らかの理由があって「.htaccess」の利用ができないといったサイトの場合でも、利用者の合意が形成できればサイト内で利用され(得)る文字符号化方法と拡張子との使い分けを設定してしまえます。

AddCharsetコマンド

AddTypeコマンドの大きな弱点に、「MIMEタイプとcharsetの設定が不可分であるために、必要な組み合わせの数だけ全て設定しなければならない」ということがあります。

『Koga's Apache page』で説明されている「AddCharset」コマンドを用いると、リソースのMIMEタイプとcharsetの設定とを分離することが可能です。このコマンドはApacheサーバ専用ですが、AddCharsetの場合、例えば「Shift_JISのHTMLファイル」を「.html.sjis」のように表します。

AddCharsetやAddTypeで利用する拡張子の選定

あまり無計画に拡張子を選ぶと後が大変ですし、また全ての文字符号化方法に対して適切な拡張子を考え出すというのも骨が折れる作業です。また、通常用いられる拡張子とは異なる拡張子を持つファイルを扱う場合、ブラウザやオーサリングツールの設定も変更する(あるいは追加設定を行う)必要があるので、あちこちで脈絡なく拡張子の増産が行われるのも困りものです。こうした困難の解消に役立つことを願って、筆者は次のような枠組みを提案します。

  1. US-ASCIIを明示するには「ASCII」を識別子とする。
  2. Shift_JISを明示するには「SJIS」を識別子とする。
  3. MIME名が7文字以下で表される場合は、MIME名を識別子とする。例えば「UTF-8」「EUC-JP」など。
  4. ISO-8859系の場合にはその識別子を「8859-1」のように用いる。
  5. ISO-2022系の場合にはその識別子を「2022jp」のように用いる。
  6. 以上に当てはまらない場合にはMIBnum値を識別子として用いる。例えばMIBnum値が17なら「mib17」のように。

上のルールでメジャーな符号化方法に対する識別子を求めると、次のようになります。

US-ASCII       ascii
ISO-8859-1     8859-1
ISO-8859-2     8859-2
ISO-8859-3     8859-3
ISO-8859-4     8859-4
ISO-8859-5     8859-5
ISO-8859-6     8859-6
ISO-8859-7     8859-7
ISO-8859-8     8859-8
ISO-8859-9     8859-9
Shift_JIS      sjis
EUC-JP         euc-jp
ISO-2022-KR    2022kr
EUC-KR         euc-kr
ISO-2022-JP    2022jp
ISO-2022-JP-2  2022jp2
UTF-7          utf-7
UTF-8          utf-8
GB2312         gb2312
Big5           big5
KOI8-R         koi8-r

AddTypeの場合には「*.htmlascii」のように、またAddCharsetの場合には「*.html.sjis」のような拡張子としてお使いください。

ローカルファイルの扱いについて

WWWに置いておく場合と同じことですが、ローカルでも文字符号化方法を統一してしまえば苦労はありません。ただし、外部からダウンロードする際に符号変換を行う場合は、注意が必要でしょう。

さて、ローカルのHTMLファイルを扱う際に文字符号化方法を識別する必要がある場合、ユーザの設定の助けを借りつつ自動判定やMETA宣言の情報を用いるブラウザが現在の主流であるかのように見えます。けれども、そうではないブラウザもあるよ、ということを紹介した記事を読んだので、META宣言に依らなくてもローカルでの文字符号化方法の識別を行う手段が現存するということを記録しておきます。

HTTP応答ヘッダの情報を記録する

fj.net.www.authoringの記事『Re: charset label』によると、Lynx の場合、読み手の「-mime_header」オプション指定により、ダウンロードしたファイルにHTTP応答ヘッダの情報をも記録させることができるそうです。残念ながらその記録形態がどのようなものであるかは未確認です。

HTTP応答ヘッダのcharsetパラメタ情報を記録する

SGML応用系であるHTMLにおいてはDOCTYPE宣言の前にコメントを記せるのですが、前述の記事によると、Alis Tangoの場合、ダウンロードするファイルの冒頭に

  <!--Des_champs_pseudo-MIME_suivent
  Content-Type: text/html; charset=ISO-2022-JP
  -->

…のようにコメント形式でcharsetパラメタ情報を記録するという手法を取っているそうです。

独自形式のアーカイブファイルを作る

Microsoft Internet Explorer 4.0x for Mac OS が既に実現していて MSIE 5.0 for MS Windows 95/NT が今回実装したという「Webアーカイブ」形式の保存を行うと、ダウンロードするページに含まれるリソースをまとめて丸ごと独自アーカイブとして保存できます。

META宣言の要不要について

冒頭にも記しましたが、HTML 4.0 仕様 5.2.2 は、文字符号化方法の識別に関して次の優先順位によって処理することを求めています。

  1. HTTP応答ヘッダのcharsetパラメタ
  2. ソース自身の符号化方法を示すMETA宣言の情報
  3. A要素やFORM要素などに記されている符号化方法に関する情報

これは、「上位に記した情報が不在だったら下位の情報を利用する」ということだけを述べているのではなく、「上位の情報と下位の情報が食い違ったら上位の情報に従う」ことをも求めている筈です。実際、HTTP 1.1 仕様は、そのように規定しています。つまり、符号変換などの結果ソース中のMETA宣言が示す内容とHTTP応答ヘッダのcharsetパラメタの内容が食い違っている場合にはHTTP応答ヘッダの方が優先される筈ですが、果たして実際のところはどうなっているでしょうか。

以下のファイルを用いてNetscape Navigator/Communicator 4.5 for PPC MacとMicrosoft Internet Explorer 4.01 for PPC Macで筆者が確認したところ、残念ながら、HTTP応答ヘッダのcharsetパラメタ値を無視してMETA宣言の内容を用いるような挙動が観察されました。

http://www.asahi-net.or.jp/‾sd5a-ucd/distinction_test/

文書の書き手に対して、現状ではMETA宣言を記した文書は符号変換に対して無力であるという注意を促しておきたいところです。

さて、META宣言の要不要をどのように考えるべきでしょうか。

前述のように他の手法も考えられるわけですが、現在のところローカルのHTMLファイルの扱いに際して有用であることは否めません。また、クライアントの種類によって調節を利かせたHTMLソースを動的に生成しているような場合、META宣言が最も有効であるようなクライアントに対してはMETA宣言によって文字符号化方法を知らせるのが一番いいでしょう。

そこで、ブラウザのベンダに対して「HTTP 1.1 クライアントを作っているつもりならば、少なくともHTTP応答ヘッダのcharsetを優先するかどうかをユーザが選択できるようにしてくれ」と頼み、またWWWサーバ管理者に対してはテキスト系リソースのHTTP応答ヘッダに適切なcharsetパラメタを与えてくれるよう頼むこととし、META宣言そのものについては「要不要」の判断を保留としておき単に仕様上の順当な地位に落ちつけていくというのがまぁ順当なのではないかと思うのですが、いかがでしょうか。


1998年12月11日初稿 12月27日誤字訂正
内田明 (UCHIDA Akira)
uchida@happy.email.ne.jp