それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

MHTML/MHT形式について。タダのメールMIMEじゃないよ.

MHTML形式について、よく分らないことを,Rubyクラス作るときにちゃんと調べた.

MHTMLは

MHTML形式は,デコメール、HTMLメール,WEBページアーカイブなどで使われる.ファイル形式。RFC2110です。

IT用語で言えばMIMEマルチパート形式ってやつ。


1ファイル中に,画像・スタイルシートJavaScript・Flash・Textなんでも入れられる.複数を含められる。バイナリはBase64エンコードして格納する


いちばんシンプルなMIME/MHTの例

RFC2110の抜粋

    From: foo1@bar.net
    To: foo2@bar.net
    Subject: A simple example
    Mime-Version: 1.0
    Content-Type: Multipart/related; boundary="boundary-example-1";
                  type=Text/HTML; start=foo3*foo1@bar.net

    --boundary-example-1
       Content-Type: Text/HTML;charset=US-ASCII
       Content-ID: <foo3*foo1@bar.net>

       ... text of the HTML document, which might contain a hyperlink
       to the other body part, for example through a statement such as:
       <IMG SRC="http://www.ietf.cnri.reston.va.us/images/ietflogo.gif"
        ALT="IETF logo">

    --boundary-example-1
       Content-Location:
             http://www.ietf.cnri.reston.va.us/images/ietflogo.gif
       Content-Type: IMAGE/GIF
       Content-Transfer-Encoding: BASE64

       R0lGODlhGAGgAPEAAP/////ZRaCgoAAAACH+PUNvcHlyaWdodCAoQykgMTk5
       NSBJRVRGLiBVbmF1dGhvcml6ZWQgZHVwbGljYXRpb24gcHJvaGliaXRlZC4A
       etc...

    --boundary-example-1--

HTMLで使う画像を入れるときのポイント

HTMLを入れて,画像・スタイルを含めるとき

Content-ID か Content-Locationを使う.

Content-location

Content-location はHTMLに書かれたパス.HTML表示に使う.ブラウザはContent-location にあれば、優先表示.無ければWEBに取りに行く.

Content-location は相対パス絶対パスのどちらでも構わない.

但し、相対パスを入れるときは Content-BASEを絶対パスでつける

Content-ID 通称 CID

Content-ID はContent-location の替わり,参照ファイル名をつける.Content-location・Content-ID両方宣言しても構わない.

Content-ID: foo@bar.net
Content-Location: CID: foo@bar.net

CIDを使うときはCIDをLocationの替わりに置くこと

実装例

 <img src="cid:XXXXX" に注目!!!

CID: に注目。HTMLファイルを見てみるとイメージがわきます.cid はデコメールで使われているおなじみ形式.ちなみにGmailはCidに対応してデコメや絵文字メールを表示してくれます.

      From: foo1@bar.net
      To: foo2@bar.net
      Subject: A simple example
      Mime-Version: 1.0
      Content-Type: Multipart/related; boundary="boundary-example-1";
                    type=Text/HTML

      --boundary-example-1
         Content-Type: Text/HTML; charset=US-ASCII

         ... text of the HTML document, which might contain a hyperlink
         to the other body part, for example through a statement such as:
         <IMG SRC="cid:foo4*foo1@bar.net" ALT="IETF logo">

      --boundary-example-1
         Content-ID: <foo4*foo1@bar.net>
         Content-Type: IMAGE/GIF
         Content-Transfer-Encoding: BASE64

         R0lGODlhGAGgAPEAAP/////ZRaCgoAAAACH+PUNvcHlyaWdodCAoQykgMTk5
         NSBJRVRGLiBVbmF1dGhvcml6ZWQgZHVwbGljYXRpb24gcHJvaGliaXRlZC4A
         etc...

      --boundary-example-1--

boundary-は境界を示す.

ファイル中に複数のファイルを埋め込む。ドコが区切りか入れないと,ファイルを読み出せない.そこでファイルに区切りを入れる.

境界の書き方。.

      --boundary-example-1
       content...
       content...
      
      --boundary-example-1
       content...
       content...
      --boundary-example-1
       content...
       content...
      --boundary-example-1--     # <- END of Content ここは  --#{境界文字列}-- と前後にダッシュが二個入る

ファイルの最終を示すBoudnary

ファイルの最終を示すには,boudaryの最後に更に -- を入れる

--boundary-example-1--# <- END of Content ここは  --#{境界文字列}-- と前後にダッシュが二個入る

境界のラストが抜けているとIEは認識しない.その他(FireFox/Opeera/Gmail)は適当に認識してくれた.

IEで読み出すときは末尾のBoundaryが必須なので注意.ココに気づくのに時間が掛かった.

まとめ


簡単ですね.ファイル中に,複数ファイルを入れられるし,入れたモノをHTML表示出来るので,とても応用性が広いと思います.だけど実装したモノが少ないので困ります.

Evernoteが使っている独自XMLスキーマよりずっと応用性が広いと思います.ファイル中に画像とHTMLを埋め込む目的であれば十分に使えます.