Web アーカイブの仕組みを探る
SPECIAL
複数の HTML ファイルを単一アーカイブにするにはどうしたらいいか…、ということで調べてみることにしました。
Web アーカイブとは
Web アーカイブとは、Microsoft Internet Explorer 5 で 「Web アーカイブ」 として保存できる、Web ページ1枚を画像等を含めて単一のファイルで保存できるようにしたものです。
この形式で保存すると、*.mht という拡張子のファイルひとつでページが保存されるので、その後の管理などが非常に楽です。
ページ単体での場合はこの IE5 に標準の機能で十分なのですが、それ以降の階層のドキュメントも一括して保存できたらいいなと思い、Web アーカイブがどのような感じで構成されているのかを調べてみることにしました。
MIME
Web ページを Web アーカイブで保存してからそれをテキストエディタで見るとわかるのですが、Web アーカイブというのは multipart/related というタイプで保存された MIME ドキュメントのようです。
この MIME ( Multipurpose Internet Mail Extensions ) というのは、電子メールで添付ファイルをつける場合などで使用される仕組みです。
MIME で表現する複合ドキュメントは、いくつかのタイプがあるようですので、まずはそのあたりを簡単に押さえておくことにします。
Content-Type: multipart/alternative
まとめられたそれぞれのパートが、すべて同じ内容であることを示すそうです。
たとえば HTML メールを送る場合に、HTML メールをサポートしていないメールソフトのために、同一内容のプレインテキストメールをセットにして送るような場合に利用します。
Content-Type: multipart/parallel
まとめられたそれぞれのパートを、できる限り同時に実行したい場合を示すそうです。
Content-Type: multipart/mixed
まとめられたそれぞれのパートは、任意の順番でデータを取り出してよいということを示すそうです。
Content-Type: multipart/related
まとめられたパートの一部が、まとめられたパートのほかのパートを参照しているということを示しているそうです。
あまり確証の持てる文書が見つからなかったのですが、IE で保存したときにはこのタイプが適用されます。
ざっとこのような感じです。
これらから察するに、複数の HTML ファイルをまとめるような場合でも、multipart/related を使用することでなんとかなりそうな感じがします。
Web アーカイブの構造
From: <Microsoft Internet Explorer 5 で保存する>
Subject: TITLE
Date: Fri, 17 May 2002 02:28:40 +0900
MIME-Version: 1.0
Content-Type: multipart/related;
boundary="----=_NextPart_000_004D_01C1FD4A.8EAC7A80";
type="text/html"
This is a multi-part message in MIME format.
------=_NextPart_000_004D_01C1FD4A.8EAC7A80
Content-Type: image/jpeg
Content-Transfer-Encoding: base64
Content-Location: http://localhost/images/logo.jpg
Hx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgASgEGA
AAAFAgMEBgEHCAEAAwEBAQEAAAAAAAAAAAAAA
BQYhMRJBUWETcbHRIjJyshWBkUJSYoKS0nOTs
------=_NextPart_000_004D_01C1FD4A.8EAC7A80
Content-Type: text/html;
charset="shift_jis"
Content-Transfer-Encoding: quoted-printable
Content-Location: http://localhost/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Frameset//EN">
<HTML>
<HEAD>
<TITLE></TITLE>
</HEAD>
<BODY>
<IMG SRC=3D"http://localhost/images/logo.jpg">
</BODY>
</HTML>
------=_NextPart_000_004D_01C1FD4A.8EAC7A80--
テキストエディタで Web アーカイブを眺めてみると、大筋は上のような構造になっているようです。
一番初めにメールっぽいヘッダーがあり、そこでそれぞれのパートを区切るテキスト文字列 ( boundary ) があります。
そして Content-Type に "multipart/related" が設定され、その中で type="text/html" が設定されています。どうやらそれ以降のパートで、この type に指定された形式のパートを見つけると、それを元となるデータとして処理するような感じです。また、start="ID" というものをつけて、指定した Content-ID: のドキュメントをディフォルトにすることもできるようです。
空行を入れることでヘッダ部分が終わり、続いて本文になります。本文の終わりには boundary で指定された文字列に "--" をつけたものが現れます。
そしてまたヘッダ、本文と続いて、再び --boundary が現れます。
これを必要回数繰り返した後、最後にまた --boundary が現れます。が、一番最後の boundary 文字列だけは、さらに語尾にも -- という文字列が付加された形になります。
内部でのリンクは Content-Location: ヘッダに指定した URL をそのまま使用すればいいようです。ただ、HTML メールのように、Content-ID: ヘッダで指定した場合は、URL の部分は cid: に ID を続けた形で、SRC="" の部分に記載するようです。
また、余談ですが、添付ファイル名は Content-Type: ヘッダに name="" を用いることで指定することができるようです。
そして Content-Disposition: ヘッダも付加されていました。この値として attachement; filename="" というように指定されます。なお、このヘッダは HTML メール内の画像には付加されないようです。
さらに余談ですけど、name="" や filename="" の値は、それぞれが干渉しないようなので、同一名の添付ファイルとかも可能です。
アーカイブを作ってみる
簡単なアーカイブから
では、複数ページ構成の Web アーカイブを作ってみることにします。
ごくごく簡単なページ構成です。始めに index.html ページを表示して、そのリンクから page1.html と page2.html へ移動することができるようにリンクを張ります。また、page1.html からは index.html と page2.html へのリンクを、そして page2.html には index.html と page1.html へのリンクを張るという形です。
Subject: TEST SITE
MIME-Version: 1.0
Content-Type: multipart/related;
boundary="PART-BREAK";
type="text/html"
This is a multi-part message in MIME format.
--PART-BREAK
Content-Type: text/html
Content-Location: http://webarchive/index.html
<html>
<head>
<title>INDEX</title>
</head>
<body>
<h1>INDEX</h1>
<ul>
<li><a href="http://webarchive/doc/page1.html">PAGE-1</a>
<li><a href="http://webarchive/doc/page2.html">PAGE-2</a>
</ul>
</body>
</html>
--PART-BREAK
Content-Type: text/html
Content-Location: http://webarchive/doc/page1.html
<html>
<head>
<title>PAGE-1</title>
</head>
<body>
<h1>PAGE-1</h1>
<ul>
<li><a href="http://webarchive/doc/page2.html">PAGE-2</a>
<li><a href="http://webarchive/index.html">INDEX</a>
</ul>
</body>
</html>
--PART-BREAK
Content-Type: text/html
Content-Location: http://webarchive/doc/page2.html
<html>
<head>
<title>PAGE-2</title>
</head>
<body>
<h1>PAGE-2</h1>
<ul>
<li><a href="http://webarchive/doc/page1.html">PAGE-1</a>
<li><a href="http://webarchive/index.html">INDEX</a>
</ul>
</body>
</html>
--PART-BREAK--
上記の内容のテキストをつくり、そのファイル名を .mht として保存します。
そしてそれをダブルクリックして IE 6 にて表示させてみると、しっかりと3ページもった Web アーカイブを作成することができました。
相対パスはできるのか
上記は架空のサイト名 http://webarchive/ をつかった絶対パスにて位置を指定しましたが、では、相対パスだとどうでしょう。
まずは Content-Location: を絶対パスのままで、リンクだけを index.html からの相対パスであらわしてみることにしました。
その場合、相対パスである doc/page1.html と doc/page2.html のどちらとも見つけることができませんでした。
続いて Content-Location: も index.html とか doc/page2.html とかいった具合に、相対パスで表現してみることにしました。
すると、ちょうど Content-Location: と一致する、index.html ページのリンクは正常に機能しましたが、その後のたとえば page1.html 内の page2.html や ../index.html といった相対パスのリンクは外れてしまいました。
このような結果から、リンクの URL は必ず Content-Location: で指定したものを使用しないといけないようです。
Content-ID: を使ってみる
では、今度は Content-Location: ではなく、HTML メールの時に用いられる Content-ID: を使うようにしてみます。
使う ID はそれぞれ、 INDEX@WEBARCHIVE / PAGE1@WEBARCHIVE / PAGE2@WEBARCHIVE とすることにします。
また、せっかくなのでファイルの名前も付けておきました。
Subject: TEST SITE
MIME-Version: 1.0
Content-Type: multipart/related;
boundary="PART-BREAK";
type="text/html"
This is a multi-part message in MIME format.
--PART-BREAK
Content-Type: text/html;
name="index.html"
Content-ID: INDEX@WEBARCHIVE
<html>
<head>
<title>INDEX</title>
</head>
<body>
<h1>INDEX</h1>
<ul>
<li><a href="cid:PAGE1@WEBARCHIVE">PAGE-1</a>
<li><a href="cid:PAGE2@WEBARCHIVE">PAGE-2</a>
</ul>
</body>
</html>
--PART-BREAK
Content-Type: text/html;
name="page1.html"
Content-ID: PAGE1@WEBARCHIVE
<html>
<head>
<title>PAGE-1</title>
</head>
<body>
<h1>PAGE-1</h1>
<ul>
<li><a href="cid:PAGE2@WEBARCHIVE">PAGE-2</a>
<li><a href="cid:INDEX@WEBARCHIVE">INDEX</a>
</ul>
</body>
</html>
--PART-BREAK
Content-Type: text/html;
name="page2.html"
Content-ID: PAGE2@WEBARCHIVE
<html>
<head>
<title>PAGE-2</title>
</head>
<body>
<h1>PAGE-2</h1>
<ul>
<li><a href="cid:PAGE1@WEBARCHIVE">PAGE-1</a>
<li><a href="cid:INDEX@WEBARCHIVE">INDEX</a>
</ul>
</body>
</html>
--PART-BREAK--
これでページを表示してみると、先ほどの Content-Location: 等を絶対パスで指定したときのように、ちゃんと3ページともにリンクをたどることができました。
初期ページ
MIME を調べていたときにちょろっと出てきた start="" を試してみようと思います。
これを、いちばん最初に出てくる Content-Type: multipart/related ヘッダの引数として入れて、ディフォルトのページが変えられるかを調べてみます。
Subject: TEST SITE
MIME-Version: 1.0
Content-Type: multipart/related;
boundary="PART-BREAK";
type="text/html";
start="PAGE2@WEBARCHIVE"
This is a multi-part message in MIME format.
--PART-BREAK
上のように、最初の Content-Type: の引数として、start="PAGE2@WEBARCHIVE" を入れてみました。
そしてブラウザで Web アーカイブを開いてみると、見事 PAGE2 がトップページとして表示されるようになりました。
Macintosh 環境
さて、今までは Windows 版の Internet Explorer 6.0 で試していたのですけど、Macintosh 版の IE ではどうなのでしょう。
ということで、早速、Mac のデスクトップへ先ほどテストした *.mht ファイルを持っていって IE 5.1 ( OS X ) に投げてみると、なんと全てのページが、というよりはひとつのページとして表示されてしまいました。
Mac 版の IE 5.1 にも、Web アーカイブの保存があったはず…。ということで違いを比べてみることにします。
とここで大きな違い、というか当たり前なのですが、Windows から持っていった *.mht ファイルは MacType/CreatorType が TEXT/LMAN になっていて、Mac 上で IE に作ってもらった方は WAFF/MSIE となっていました。
なのでとりあえずファイルタイプを WAFF/MSIE に変更してみましたが失敗。
そして中身をテキストエディタで比べてみると、なんとも大きな違いが発覚しました。
Mac 版の IE で保存した Web アーカイブには、なにやらバイナリデータのような形で、ヘッダが付加されているではありませんか。
なんと MIME による multipart ではないようですね…。根本的に構造が違う様子なので、とりあえず深追いせずに投了しておきます ^^;
実験終了…
Macintosh 版にはとりあえずお手上げですが、Windows 版はとりあえず実用レベルな感じまで調査が終わった気がするので終了です。
この multipart は入れ子構造にすることもできるようです。
HTML メールの場合、対応していないメールソフトのことも考えて、まずは multipart/alternative によって text/html の他に text/plain も用意して対処するようです。
その上で、text/html を用意するのですが、これが実際には入れ子構造になっていて、トップは multipart/related になり、その中のパートとして text/html が存在するといった感じになっています。