メール送信でタイトルが化ける原因
漢字や中国語のようなマルチバイトを含むメールを送信するときにハマったので記録。
文字コードはとーぜんutf8だしょ。 という事でヘッダに「text/plain; charset=utf-8」を指定。
メール本文もutf8で記述したものをセットした。
タイトルも同じくutf8で記述したものをセットした。
でも化けた。
タイトルだけ化けた。
なぜか?
タイトル(Subject)はヘッダなのだ。
ヘッダで「このメールはutf8だぜ」って指定している。
そのため本文は化けない。
しかし、同じくヘッダであるSubjectはutf8とは言われていない。
更にいうとメールのヘッダに8ビット文字は使用出来ない。
使えるのは7ビット文字だ。
どうすればいいか?
Subjectにも「これはutf8だぜ」って指定すればいい。
メールの規則によればこうなる。
=?utf-8?タイトル?=
これをSubjectに入れてあげると「タイトル」って文字はutf8だぜ って認識してくれる。
でもこれだけではダメ。ちらっと書いたけれど
使えるのは7ビット文字だ。
という事はBASE64エンコードする必要がある。
「タイトル」はBASE64エンコードすると「44K/44Kk44OI44Or」になる。
で、こうやって書いてSubjectにセットする。
=?utf-8?B?44K/44Kk44OI44Or?=
B?って書いてあげると「この文字列はBASE64エンコードされてるんだぜ」って意味になる。
ヘッダにこう書かれていると、メールを受け取ったメーラーは
こうやって解釈する。
「44K/44Kk44OI44Or って文字列はBASE64デコードしてくれよな。
あと、こいつはutf8で書かれているからよっ よろしくな」
この仕組みを分かっていなかった僕はハマった。
PerlだとEncode.pmがとても便利。
use utf8; use Encode; my $subject = encode('MIME-Header', 'タイトル');
これで$subjectには「=?utf8?B?44K/44Kk44OI44Or?=」が格納されている。
ちなみに、このヘッダへの文字コード指定やBASE64指定はSubjectに限った事ではなく、FromやToなど他のヘッダにも使用出来る。
よくアドレスに日本語の名前が付いていたりするのは、こういうヘッダにしているからだった。
utf8ではなくjisコードを指定したい場合は=?iso-2022-jp?B? という感じになるみたい。(試してないです)