Now browsing the archives for 3月, 2008.

nsIWebBrowserPersist の基本的な使い方 (4) ~ POST メソッド

HTTP の POST メソッドで Web サーバへ要求し、その回答結果をファイルへ保存する。
ほとんど nsIHttpChannel の使用がメインですので、ファイル保存する場合以外にも応用可能です。
また、サンプルコードは nsIWebBrowserPersist の基本的な使い方 (1) ~ 基本形 をベースとしており、一部省略しています。

saveURI の場合

saveURI の第4引数 aPostData を使えばできるはずだが、現在調査中…

saveChannel の場合

例によって nsIURL オブジェクトから nsIHttpChannel オブジェクトを生成する。

// make nsIHttpChannel
var ioSvc = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var channel = ioSvc.newChannelFromURI(url).QueryInterface(Ci.nsIHttpChannel);

POST するデータは以下のような文字列とする。以下の場合は文字列全体を単純に encodeURI 関数で URL エンコードすれば良いが、キーや値に & や = を含む場合を考慮した、より一般的な URL エンコードの方法については後述する。

var postStr = encodeURI("foo=bar&baz=eek&名前=太郎");

POST する文字列から nsIStringInputStream を生成し、 nsIHttpChannel を nsIUploadChannel へ QI してからストリームをセットする。今回の例では Content-type は application/x-www-form-urlencoded だが、 XML データを POST する場合などは適宜 application/xml とかにする。

// make nsIStringInputStream to post
var inputStream = Cc["@mozilla.org/io/string-input-stream;1"]
                  .createInstance(Ci.nsIStringInputStream);
inputStream.setData(postStr, postStr.length);

// set nsIStringInputStream to nsIUploadChannel
var uploadChannel = channel.QueryInterface(Ci.nsIUploadChannel);
uploadChannel.setUploadStream(inputStream, "application/x-www-form-urlencoded", -1);

nsIWebBrowserPersist で送信する前に、 nsIHttpChannel オブジェクトの requestMethod プロパティを POST にするのを忘れずに。これをしないと、なぜか PUT メソッドでの要求になってしまう。

// must do this otherwise request method will be "PUT"
channel.requestMethod = "POST";

// save channel to file
var wbp = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
          .createInstance(Ci.nsIWebBrowserPersist);
wbp.saveChannel(channel, file);

POST する文字列の URL エンコード

POST する文字列がユーザからの入力である場合、 & や = を含む場合を考慮し、以下のように encodeURIComponent を使って URL エンコードする。

// make string to post
var postObj = {
    "foo": "bar",
    "baz": "eek",
    "名前": "山田=太郎&花子",
};
var pairs = [];
for (var [key, val] in Iterator(postObj)) {
    pairs.push(encodeURIComponent(key) + "=" + encodeURIComponent(val));
}
var postStr = pairs.join("&");

関連記事

nsIWebBrowserPersist の基本的な使い方 (1) ~ 基本形
nsIWebBrowserPersist の基本的な使い方 (2) ~ persistFlags
nsIWebBrowserPersist の基本的な使い方 (3) ~ 各種ヘッダの追加
nsIWebBrowserPersist の基本的な使い方 (4) ~ POST メソッド
nsIWebBrowserPersist の基本的な使い方 (5) ~ ダウンロード進捗状況
つづく…?

TOP

FireGestures キープレスジェスチャの機能割り当て

現在のところ、 FireGestures のキープレスジェスチャは、以下のように割り当てが固定されていた。

  • Shift キーを押しながらマウスジェスチャ: マウスが通過したリンクをタブで開く
  • Ctrl キーを押しながらマウスジェスチャ: マウスが通過したリンク先を保存する

しかし、 AMO のディスカッション Is it possible to harmonize Keypress gestures ? にて、 Firefox の標準動作では、

  • リンク上で Ctrl + クリック: リンクをタブで開く
  • リンク上で Alt + クリック: リンク先を保存する

なので、これに合わせて以下のような割り当てにしたらどうかという提案があった。

  • Ctrl キーを押しながらマウスジェスチャ: マウスが通過したリンクをタブで開く
  • Alt キーを押しながらマウスジェスチャ: マウスが通過したリンク先を保存する

なるほど確かにこれは理にかなっていると思ったが、残念なことに Linux では Alt キーを押しながらの右クリックはアプリケーションのコンテキストメニューを表示するための特別な役割があるようで、リンク上で Alt + クリックや、 Alt キーを押しながらのジェスチャができないことがわかった。

やはり、キープレスジェスチャは Ctrl / Shift キー、ということにするしかなさそうだ。

TOP