Last update: 2000/6/23
結論からいえばブラウザ (Netscape 4.x) が一番悪い。Apache 側の対応としても考えるべきところはあるが。
Apache 1.3.12 にアップグレードしたとたん、一部のブラウザが文 字化けを起こす、という現象が発生するようになった。
この文字化けは「常に発生」というわけではなく、ある一定の条件 のもとで発生する。メーリングリストでのレポートなどによれば、そ の現象は、たとえば、以下のような場合にみられるようである。 [1]。
Apache の設定ファイル (httpd.conf や .htaccess など) の Redirect や RedirectMatch など、「他のURLに飛ばす」機能を使っ て、特定の URL から他の URL に「飛ばす」指定を行なった場合
http://www.example.com/~joe のような URL をブラ ウザに指定して http://www.example.com/~joe/ を 表示させる、といった場合
「AuthType Basic」などでユーザ認証を行ない、認証後に表示される ページ
いずれも、結果として表示されるページの HTML に META タグを使って
<META HTTP-EQUIV="Content-type" CONTENT="text/html; charset=ISO-2022-JP">
のように charset を明示して書いておいてもそれをブラウザは無視して、 ISO-8859-1 として表示してしまう、というものである。
ただし、mod_mimeのAddCharset 機能などを使って、飛び先のページをサーバから送り 出す際、その HTTP レスポンスにおいて
Content-Type: text/html; charset=ISO-2022-JP
のように、charset を HTTP で明示させている場合には化けない。たとえば今ご覧になっているこのページみたいに。
また、化けるといっても、すべてのブラウザで問題があるわけではなく、 Netscape の version 4 系列での問題の発生が確認されており、Internet Explorer や Netscape の ver.3 や開発中の Mozilla など、他のブラウザ では問題がない。
この問題は 2 つの要因によってひきおこされている。
Apache の 1.3.12 から、Redirect (301 Moved Permanetly、302 Moved Temporarily) や 401 (Unauthorized) などをクライアント (ブラウザ) に送るための処理を行なう Apache の ap_send_error_response() というルーチン内において、 charset=iso-8859-1 が強制的にセットされるようになった。
つまり 301 や 401 などの HTTP レスポンスが 1.3.11 までは
Content-Type: text/html
だったのが、1.3.12 から
Content-Type: text/html; charset=iso-8859-1
に変更された。
Apache 1.3.12 において A. のような変更が加えられたのは Cross Site Scripting Bug と呼ばれるセキュリティ上の問題への 対応のためである。この問題については CERT による勧告 [1]や、Apache としての対応 [2]を参照。
なお、Debian GNU/Linux (potato) の Apache 1.3.9 については、 1.3.12 で加えられた変更が独自に適用されている。これは securtiy 上の問 題であるからである。同様に、1.3.12 以前の版でも同様の対処が行なわれて いる場合があるなら、この問題は発生する。
301 や 401 の後に表示するページの META タグにいかなる charset が設定されていても、そのページ直前の (301 や 401 の) HTTP レスポンスで返された charset のほうを見てしまう、という バグが Netscape 4.x にはある。リロードした場合など、キャッシュ から読みこむ場合にはMETA タグのほうを読みにいくので問題はな い。
これついては Netscape 4.x の問題といえるし、一番の原因だろう。
CSS バグについては
セキュリティホール memo - 2000.02.07
や
Cross-Site Scripting問題とは?
などが参考になります。
ところで CSS 対応でナゼ charset=iso-8859-1 などを付けるよう にしたのか、といえば、この charset 情報を元にサーバより送られ た HTML ドキュメントの validation を行ない、不審なものを実行し たりするのを避ける、ということのようです。たぶん。あと、 HTTP/1.1 的には charset パラメタは必須、でしたっけ。
世の中から buggy なブラウザが消えることを待つ (ほら、Netscape 4.x って CSS のバグは多いし...。がんばれ Mozilla)
Apache にパッチを当てて、
ap_send_error_response()
の
iso-8859-1
を削る。ちょっと後向きだけど
Apache にパッチを当てて、
ap_send_error_response()
の
iso-8859-1
を iso-2022-jp
などに変
える
Netscape 4.x は iso-2022-jp
を「文字コード自動
判定(日本語)」として処理するようなので、飛び先 URL が日本語
のページならそれなりにうまくいきそう。
また、「ウチのサイトは Shift_JISオンリー」とか、「飛び先はす べて把握できる」なら問題ないかも
Apache にパッチを当てて、ap_send_error_response() の 後に読みこまれるであろう HTML の charset を推測して charset=??? をセットするパッチを作る
同じサイト内ならともかく、他所にあるサーバに飛ばしてたら どうする?
AddCharset などを使って、つねに charset= のヘッダを 付けるように心がける
AddCharset と ErrorDocument を使って、30x や 40x 系のレス ポンスに対し、charset=iso-2022-jp などのヘッダの付いたドキュ メントを返すようにする
下記に示すメーリングリストでの議論を参考にしてください
以降の 3 つのスレッド
FIXME: ところどころ説明なしに使っている語句がある のが...。Apache MLのスレッドはざっと読んだだけで、ちゃんと 読めてないかも。自分自身で内容の検証もしてないし...
FIXMEというかTODO: Apache 2.0αでの charset まわ りのハンドリングについての事情や、Apache 1.3.12 での charset ま わりの他のバグについての記述もしたい。
[戻る]