X-0015 URI で示されたリソースをファイルに保存する

URI で示されたリソースをファイルとして保存する場合、リンク先を保存などで実際に使われている処理を参考にすると、簡単に記述することができます。

nsIWebBrowserPersist を使う

リソースの保存には nsIWebBrowserPersist の saveURI というメソッドが使えます。このメソッドは引数として URI オブジェクトとファイルオブジェクトを必要とします。

下準備

まず、 URI を示す文字列から URI オブジェクトを作ります。

var targetURI = Components.classes['@mozilla.org/network/io-service;1']
                          .getService(Components.interfaces.nsIIOService)
                          .newURI(uri, null, null);

次に、ファイルパスを示す文字列からファイルオブジェクトを作ります。

var targetFile = Components.classes['@mozilla.org/file/local;1']
                           .createInstance(Components.interfaces.nsILocalFile);
targetFile.initWithPath(path);

この辺の処理はよく使うことになると思いますので、 URI やパスからこれらのオブジェクトを生成する関数にしておくと便利でしょう。

ヒストリからキャッシュを得る

キャッシュからファイルを保存できるように、キャッシュの情報を得ておきましょう。キャッシュを使わない場合、この処理は不要です。

var postData = null;
try {
    var SH = getWebNavigation().sessionHistory;
    var entry = SH.getEntryAtIndex(SH.index, false)
                  .QueryInterface(Components.interfaces.nsISHEntry);
    postData = entry.postData;
} catch (e) {}

getWebNavigation() は、 Navigator 内部で使用されている関数の一つで、自作の XUL アプリでは使えません。その場合、 nsIWebNavigation のオブジェクトを自分で作る必要があります。

URI をファイルに保存する

ここまできたら、あとは nsIWebBrowserPersist のインスタンスを生成して、 saveURI メソッドにそれぞれを渡すだけです。

var PERSIST = Components.classes['@mozilla.org/embedding/browser/nsWebBrowserPersist;1']
                        .createInstance(Components.interfaces.nsIWebBrowserPersist);
PERSIST.saveURI(targetURI, postData, targetFile);

読み込みが中断されたりしてファイルが保存できなかった場合のエラー処理を行わないなら、これで完了です。

ただ、 @mozilla.org/embedding/browser/nsWebBrowserPersist;1 というコンポーネント ID は NS6.2.2 の段階では使えません。 nsIWebBrowserPersist の実装も違っているようです。というか、公式には nsIWebBrowserPersist 自体使えないことになっているようです。少々イリーガルな方法ですが、以下のようにすると、 NS6 でも saveURI を使うことができます。

var PERSIST;
try {
    PERSIST = Components.classes['@mozilla.org/embedding/browser/nsWebBrowserPersist;1']
                        .createInstance(Components.interfaces.nsIWebBrowserPersist);
    PERSIST.saveURI(targetURI, postData, targetFile);
} catch(e) {
    try {
        PERSIST = Components.classes['@mozilla.org/embedding/browser/nsWebBrowser;1']
                            .createInstance(Components.interfaces.nsIWebBrowserPersist);
        PERSIST.saveURI(targetURI, postData, targetFile.path);
    } catch(e) {
    }
}

NS6 向けの処理では、コンポーネント ID が違うのと、 saveURI に渡す引数がファイルオブジェクトではなくファイルパスの文字列である点に注意して下さい。