2013年4月10日

ウェブページを保存するという事

UnMHT は開発当初は (名前が示す通り) MHT を表示するためのアドオンだったんだけど、途中でリクエストから保存機能を付ける事になったわけです。

で、ウェブページを保存する、といっても今の時代多くのページは動的なコンテンツを含んでるので、「どう」保存するかというのが結果に影響するのです。

UnMHT では現在3つの方法を提供しています
  1. 現在の状態
    HTML ファイルについては保存するタイミングの DOM ツリーから再構築する
  2. 現在の状態 (スクリプト削除)
    「現在の状態」からスクリプト関係の要素、属性だけ削除する
  3. 元のファイル
    HTML ファイルについてはサーバが返したものを使う
ウェブページが JavaScript を一切使用していなければどの方法でも結果は同じです。1、2と3の間で HTML のソースに多少の差はありますが、見た目には影響しません。

ところが JavaScript が使われていると事情が変わります。大きく影響するのは以下のようなもの。


ページの主要なコンテンツが JavaScript で生成される


「元のファイル」での保存には致命的です。早い話が保存したい内容がファイルに入っていないワケですから、「ウェブページを保存した」 とは言えない状態です。

じゃあ「現在の状態」なら良いかというと実はそうでもなくて、主要なコンテンツが2つ表示されるか、保存された内容が MHT ファイルを開いた途端消し飛んで新しい内容 (もしくは空白)に置き換わるか、という事が発生したりします。

これは最近何度かフォーラムで報告された画像表示の JavaScript の問題も含みます。画像をクリックするとページが暗くなって真ん中に拡大画像が表示される、というスタイルは結構見かけるようになりました。画像を表示する際に背景を生成する場合、この背景に相当する要素が重複して作成され、id も重複したために機能が正しく動作しないという事が起きると、見るも無惨にページの上半分が真っ黒になったりするのです。

また、生成されたものが DOM に直接反映されるものでなければ「現在の状態」でも保存できません。具体例でいうと Canvas の内容です。Canvas の内容は HTML の記述とは独立して存在しているので、その状態を保存した上で続きから動き始めるという事ができません。

UnMHT では、例外的な挙動として「現在の状態 (スクリプト削除)」の場合のみ Canvas の内容を data URI にして background-image として表示しています。これは JavaScript がこれ以降動かないために可能な回避策であり、「現在の状態」では使えない方法です。

結局この場合、ウェブページを意図通りに保存できるのは「現在の状態 (スクリプト削除)」だけです。

ページのどうでもいいコンテンツが JavaScript で生成される

「現在の状態」での保存の場合に不具合が出ます。これは主に広告を動的に差し込むという状況なので、早い話が広告が沢山出るのです。 2つに増える事もあれば、広告の差し込み方によっては3つ4つに増えます。保存したい情報は保存されているので「ウェブページを保存する」という希望は叶えられますが見づらくなります。

「元のファイル」の場合には広告は改めて1つだけ差し込まれる事になりますし、「現在の状態 (スクリプト削除)」であれば既に差し込まれていた広告が1つ表示されるだけです。

本来の URL でない場合にページが遷移する

「ウェブページを保存したい」のは「ユーザ」ですが、「ウェブページを保存してほしい」のは誰でしょう?

そんな人はほとんど居ないんじゃないでしょうか。オンラインマニュアルみたいに、古い情報を参照され続ける事が困るとか、理由は色々あると思います。いづれにせよ、ウェブサイトは保存する事を前提には作られていないのです。

その最たる例がコレです。URL をチェックして、オリジナルでないならオリジナルのページに遷移する。つまりオリジナル以外の場所に保存されたページは閲覧不可というワケです。

ウェブページの制作者の意図に忠実に従うなら、「そのようなウェブページは保存できない」というのが答えでしょう。

偶然他の用途で開発していた「 現在の状態 (スクリプト削除)」がユーザ側の希望を叶える結果にはなりましたが、これについては本当に正しかったのか未だに疑問ではあります。

ページの主要なコンテンツが JavaScript で動く

万能に思える「現在の状態 (スクリプト削除)」ですが、この場合は困りモノです。

例えばメニューが JavaScript で動くようなページだと、ページ遷移ができなくなります。もちろんそこが保存する目的でなければ問題はありませんけど。

また、オーディオやビデオを含むページで、その再生制御に JavaScript が使用されているとしたら、JavaScript を削除してしまうと再生できなくなってしまいます。こっちは重大な問題です。

「ウェブページを保存する」というのが「今見えている状態を保存する」ではなく「今動いている状態を保存する」となると、スクリプトを削除してはいけないのです。

ページの内容がブラウザによって異なる

他とはやや違った問題ではあるのですが、互換性への影響です。

これは何も JavaScript に限った話ではなく、サーバサイドで生成されるもの、クライアントに返されるものが違うという場合にも発生する問題です。UnMHT は Firefox 用のアドオンですから、当然保存する際のページの内容は Firefox 用になっているわけです。HTML や CSS のサポートの違いからくるハックであるとか、ブラウザによって見せる内容を変えたいであるとか、色々な理由からページの内容や挙動をブラウザごとに分けているウェブサイトも少なくはないでしょう。

そうなると、UnMHT で保存した MHT ファイルは、本来構造的には IE でも Opera でも開けるはずなのに、ページの内容が適切ではないために Firefox でしか見れない MHT ファイルになってしまうという事が起こります。

JavaScript で分岐をしている場合、「元のファイル」で保存する事で多少回避できるかもしれません。ただし、分岐した結果追加で読み込むファイルがブラウザごとに違う場合、不完全な保存状態という事になってしまいます。

サーバサイドで分岐している場合、もうこれは手のうちようがありません。Firefox 専用の MHT ファイルの出来上がりです。

----

と、いうように、「ウェブページを保存する」といっても何のために保存するか、どういうページであるかによって、適切な保存方法が変わってくるのですが、はたしてユーザはこの違いを一目で認識し、適切な保存方法を選択できるでしょうか。

おそらくそれはムリでしょう。作ってる私だってムリです。一旦保存して、開いてみて、不具合が出たら原因を考える、という手順を踏まないと適切な保存方法は選択できません。 一番無難なのが「現在の状態 (スクリプト削除)」だ、というくらいです。

また、そもそも3つから選択させるという事自体が混乱をうむような気もします。今の名前付け「現在の状態」「元のファイル」等が分かりやすいかというとそうでもないわけですし。

勢いで付けた保存機能ですけど、本格的に考えてみると奥が深いものですね。

0 件のコメント:

コメントを投稿