― MozillaZine.jp フォーラムは Mozilla 製品に関する情報交換の場です ―



All times are UTC + 9 hours

新しいトピックを投稿する トピックへ返信する  [ 11 件の記事 ] 
作成者 メッセージ
投稿記事Posted: 2008年9月08日(月) 21:24 
オフライン

登録日時: 2008年8月24日(日) 21:09
記事: 33
2008/09/10 編集

Progress Listenerでリダイレクトを検知するために、以下のように STATE_REDIRECTING を使おうと思ったんですがどうもこれではダメなようです。どうやればちゃんと働くでしょうか。

コード:
window.addEventListener("load", function() { sample.init(); }, false);

var sample = {
   init : function() {
       gBrowser.addProgressListener(testListener);
   }
}

var testListener = {
   QueryInterface : function(aIID) {
      if (aIID.equals(Components.interfaces.nsIWebProgressListener)
            || aIID.equals(Components.interfaces.nsISupportsWeakReference)
            || aIID.equals(Components.interfaces.nsISupports))
         return this;
      throw Components.results.NS_NOINTERFACE;
   },

   onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) {
      if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_REDIRECTING) {
         alert("リダイレクト");
      }
      return 0;
   },
   onLocationChange : function() {return 0;},
   onProgressChange : function() {return 0;},
   onStatusChange : function() {return 0;},
   onSecurityChange : function() {return 0;},
   onLinkIconAvailable : function() {return 0;}
}


追記:
それからSTATE_IS_DOCUMENTはドキュメントでないときでもドキュメントと判断してしまいます。

_________________
masahal
antispam826-public at yahoo.co.jp
http://masahal.web.fc2.com/


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月11日(木) 13:09 
オフライン
Moderator

登録日時: 2007年5月03日(木) 01:11
記事: 92
お住まい: 東京
Progress Listenerを使う場合は、tabbrowser.xmlの中でそうしているように、Progress Filterを使うといいかもしれません。

コード:
var filter = Cc['@mozilla.org/appshell/component/browser-status-filter;1']
                     .createInstance(Ci.nsIWebProgress);
gBrowser.webProgress.addProgressListener(filter, Ci.nsIWebProgress.NOTIFY_ALL);
var listener = new MyProgressListener();
filter.addProgressListener(listener, Ci.nsIWebProgress.NOTIFY_ALL);


最初にすべての情報をProgress Filterが受け取って、そのうちページそのものの読み込みに関する情報だけがProgress Listenerに渡されるという、文字通りフィルタの役割をする物です。

Firefox 3だけに対応するのでよければ、nsINavHistoryServiceのオブザーバも使えるかもしれません。
オブザーバのonVisitメソッドに渡される引数の中に、訪問の方法(リンクをクリックしたのか、リダイレクトなのか、など)が含まれています。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月12日(金) 02:26 
オフライン

登録日時: 2008年8月24日(日) 21:09
記事: 33
すいません。ちょっとコードの使い方がわからないんですが……。
status filter をNOTIFY_ALLにすれば全ての情報が渡されると言うことなんでしょうか。
でも、その場合でもリダイレクトは検知できてないようなんですが……。

_________________
masahal
antispam826-public at yahoo.co.jp
http://masahal.web.fc2.com/


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月14日(日) 01:06 
オフライン
Moderator

登録日時: 2006年10月29日(日) 21:56
記事: 472
Piro さんが書きました:
最初にすべての情報をProgress Filterが受け取って、そのうちページそのものの読み込みに関する情報だけがProgress Listenerに渡されるという、文字通りフィルタの役割をする物です。

STATE_REDIRECTING を検知したいという話ですが、Progress Filter では STATE_REDIRECTING はフィルタを通らないようなのでダメだと思います。

また、masahal さんのコードのように、gBrowser.addProgressListener() とした場合は Progress Filter で受け取ったものを分配する形(gBrowser は、tabbrowser 要素です)なので、やはり STATE_REDIRECTING は落とされていると思います。
tabbrowser 要素の addProgressListener ではなく、browser 要素の webProgress に対して直接 addProgressListener すればいいんじゃないでしょうか。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月14日(日) 11:54 
オフライン
Moderator

登録日時: 2007年5月03日(木) 01:11
記事: 92
お住まい: 東京
あ さんが書きました:
Piro さんが書きました:
また、masahal さんのコードのように、gBrowser.addProgressListener() とした場合は Progress Filter で受け取ったものを分配する形(gBrowser は、tabbrowser 要素です)なので、やはり STATE_REDIRECTING は落とされていると思います。
tabbrowser 要素の addProgressListener ではなく、browser 要素の webProgress に対して直接 addProgressListener すればいいんじゃないでしょうか。


おおお……そんな仕様になっていたとは。
自分がやるときはいつもはTabOpenとかのイベントを拾って直接event.target.linkedBrowser.webProgress.addProgressListenerしてたので、気付いていませんでした。
説明やログをちゃんと読まないまま適当発言してすみません。>ALL


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月14日(日) 12:29 
オフライン
Moderator

登録日時: 2007年5月03日(木) 01:11
記事: 92
お住まい: 東京
このままだとゴミレスでしかないので、上のレスで少し書いたnsINavHistoryServiceを使う方法についてサンプルを示しておきます。

コード:
var observer = {
    onBeginUpdateBatch : function() {},
    onEndUpdateBatch : function() {},
    onVisit : function(aURI, aVisitID, aTime, aSessionID, aReferringID, aTransitionType) {
        if (aTransitionType == Ci.nsINavHistoryService.TRANSITION_REDIRECT_PERMANENT)
            Application.console.log(aURI.spec);
    },
    onTitleChanged : function() {},
    onDeleteURI : function() {},
    onClearHistory : function() {},
    onPageChanged : function() {},
    onPageExpired : function() {}
};

var historyService = Cc['@mozilla.org/browser/nav-history-service;1'].getService(Ci.nsINavHistoryService);
historyService.addObserver(observer, false);


ただ、これで捕捉できるのは履歴項目が作成されるタイミングでのことのようで、「リダイレクトが行われた瞬間」よりは若干遅れてonVisitが呼ばれます。
あとPlacesのAPIなので当然ながらFirefox 2では動作しません。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月15日(月) 14:51 
オフライン

登録日時: 2008年8月24日(日) 21:09
記事: 33
Piro さんが書きました:
ただ、これで捕捉できるのは履歴項目が作成されるタイミングでのことのようで、「リダイレクトが行われた瞬間」よりは若干遅れてonVisitが呼ばれます。
あとPlacesのAPIなので当然ながらFirefox 2では動作しません。


やってみたんですが、1秒ぐらい遅れが出るようなのでちょっと使えないようです。Progeress Listenerの方でもやってみたんですが、どうもリダイレクト前のURIを取得してしまったり、本来取得すべきでないリダイレクトを取得してしまったりするようなので、こっちもダメっぽいです。

コード:
window.addEventListener("load", function() { test.init(); }, false);

var test = {
   init : function() {
      var appcontent = document.getElementById("appcontent");   // browser
      if(appcontent) appcontent.addEventListener("DOMContentLoaded", test.onPageLoad, true);
      gBrowser.addProgressListener(testListener);
   },
   onPageLoad : function(aEvent) {
      var browser =  gBrowser.getBrowserForDocument( aEvent.originalTarget );
      browser.removeProgressListener(redirectListener);
   }
}

var testListener = {
   QueryInterface : function(aIID) {
      if (aIID.equals(Components.interfaces.nsIWebProgressListener)
            || aIID.equals(Components.interfaces.nsISupportsWeakReference)
            || aIID.equals(Components.interfaces.nsISupports))
         return this;
      throw Components.results.NS_NOINTERFACE;
   },

   onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) {
      var browser =  gBrowser.getBrowserForDocument( aWebProgress.DOMWindow.document);
      var STATE_START = Components.interfaces.nsIWebProgressListener.STATE_START;
      if (aFlag & STATE_START) {
         browser.addProgressListener(redirectListener);
      }
      return 0;
   },
   onLocationChange : function() { return 0; },
   onProgressChange : function() { return 0; },
   onStatusChange : function() { return 0; },
   onSecurityChange : function() { return 0; },
   onLinkIconAvailable : function() { return 0; }
}
var redirectListener = {
   QueryInterface : function(aIID) {
      if (aIID.equals(Components.interfaces.nsIWebProgressListener)
            || aIID.equals(Components.interfaces.nsISupportsWeakReference)
            || aIID.equals(Components.interfaces.nsISupports))
         return this;
      throw Components.results.NS_NOINTERFACE;
   },
   onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) {
      if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_REDIRECTING) {
         alert(aRequest.name);
      }
      return 0;
   },
   onLocationChange : function() { return 0; },
   onProgressChange : function() { return 0; },
   onStatusChange : function() { return 0; },
   onSecurityChange : function() { return 0; },
   onLinkIconAvailable : function() { return 0; }
}

_________________
masahal
antispam826-public at yahoo.co.jp
http://masahal.web.fc2.com/


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月18日(木) 01:18 
オフライン
Moderator

登録日時: 2006年10月29日(日) 21:56
記事: 472
masahal さんが書きました:
Progeress Listenerの方でもやってみたんですが、どうもリダイレクト前のURIを取得してしまったり、

リダイレクト先の URI を取得したいということだったのでしょうか。

STATE_REDIRECTING というのは、リクエストしてみたら Moved なレスポンスが返ってきた、という状況です。
(続けて、そこで指定された URI を自動的に読み込むところまでも含めて リダイレクト と呼ぶ場合もありますが、STATE_REDIRECTING はそうではありません。)
なので、STATE_REDIRECTING が発生するリクエストというのは、リダイレクト元に対するリクエストです。
「そこで指定された URI を自動的に読み込む」ときの URI を取得したいのであれば、STATE_REDIRECTING が発生した後で始まるリクエストの URI を取得する必要があります。
(ただし、それが直後に始まる(=別のリクエストは間に割り込んでこない)ことが保証されているのかどうかは、不明です。)

なお、「直後」とかを自分で実装しようとすると、自分で状態を保存しておく必要ができてしまいますが、安直にやろうとすれば、nsIChannel の originalURI にリダイレクト元の URI が入っていることを利用すると
コード:
var redirectListener = {
   QueryInterface : function(aIID) {
      if (aIID.equals(Components.interfaces.nsIWebProgressListener)
            || aIID.equals(Components.interfaces.nsISupportsWeakReference)
            || aIID.equals(Components.interfaces.nsISupports))
         return this;
      throw Components.results.NS_NOINTERFACE;
   },
   onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) {
      if (aFlag & Components.interfaces.nsIWebProgressListener.STATE_START) {
        if (aRequest instanceof Components.interfaces.nsIChannel) {
          if (aRequest.URI.spec != aRequest.originalURI.spec) {
            alert(aRequest.name);
          }
        }
      }
      return 0;
   },
   onLocationChange : function() { return 0; },
   onProgressChange : function() { return 0; },
   onStatusChange : function() { return 0; },
   onSecurityChange : function() { return 0; },
   onLinkIconAvailable : function() { return 0; }
}
ともできます。
が、リダイレクトでなくても URI と originalURI が別物の場合もあるので、余計なものを拾っても大丈夫なようにするか、あるいは STATE_REDIRECTING の後でなければ無視するとか、が必要かもしれません。(あら、安直ではなくなってしまった。)
また、元と同じ URI にリダイレクト(=ループ)も検出できません。

余計なものを拾ってはいけなくて、かつリダイレクト後の URI が必要、ということなのであれば、Progress Listener はあきらめて nsIChannelEventSink の onChannelRedirect を使う方がいいのかもしれません。

masahal さんが書きました:
本来取得すべきでないリダイレクトを取得してしまったりするようなので、こっちもダメっぽいです。

どういったものが本来取得すべきで、どういったものがすべきでないのでしょうか?


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月25日(木) 01:50 
オフライン

登録日時: 2008年8月24日(日) 21:09
記事: 33
返信遅れてすいません。
「redirectListener」の部分をあさんのコードに差し替えたところ、ちゃんとうまくいきました。
今のところ余計なものを拾ったりということはありません。

あ さんが書きました:
どういったものが本来取得すべきで、どういったものがすべきでないのでしょうか?


自分の元のコードだと、例えばYahoo!ファイナンスを開くと
http://rd.yahoo.co.jp/jpr_finance/tpu/n ... s/new2.gif とかが検出されてました。

_________________
masahal
antispam826-public at yahoo.co.jp
http://masahal.web.fc2.com/


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年9月27日(土) 22:18 
オフライン
Moderator

登録日時: 2006年10月29日(日) 21:56
記事: 472
masahal さんが書きました:
「redirectListener」の部分をあさんのコードに差し替えたところ、ちゃんとうまくいきました。
今のところ余計なものを拾ったりということはありません。

http:// ならそこそこ行けるのではないかと思いますが、chrome:// とか resource:// とか入れられるとリダイレクト扱いになってしまうと思いますので、お気をつけください。

masahal さんが書きました:
あ さんが書きました:
どういったものが本来取得すべきで、どういったものがすべきでないのでしょうか?


自分の元のコードだと、例えばYahoo!ファイナンスを開くと
http://rd.yahoo.co.jp/jpr_finance/tpu/n ... s/new2.gif とかが検出されてました。

それもリダイレクトであることには違いありませんから、本来取得すべきかどうかという話ではなくて、あなたの使い方に対して取得してほしいかどうかという話ですね。

「あなたの使い方」についての情報が不足していて前提条件がはっきりしない割には、前提条件が既知だったかのような書き方が見受けられます。
たとえば、遅れがあってはいけないというような前提条件は最初書かれていなかったのに、Piro さんがせっかくコードを書いてくださった後に「1秒ぐらい遅れが出るようなのでちょっと使えないようです」とか、もう少し違った書き方はないものでしょうか。


通報する
ページトップ
 プロフィール  
引用付きで返信する  
投稿記事Posted: 2008年10月01日(水) 00:28 
オフライン

登録日時: 2008年8月24日(日) 21:09
記事: 33
あ さんが書きました:
「あなたの使い方」についての情報が不足していて前提条件がはっきりしない割には、前提条件が既知だったかのような書き方が見受けられます。
たとえば、遅れがあってはいけないというような前提条件は最初書かれていなかったのに、Piro さんがせっかくコードを書いてくださった後に「1秒ぐらい遅れが出るようなのでちょっと使えないようです」とか、もう少し違った書き方はないものでしょうか。


すいません。以後気をつけます。

_________________
masahal
antispam826-public at yahoo.co.jp
http://masahal.web.fc2.com/


通報する
ページトップ
 プロフィール  
引用付きで返信する  
期間内表示:  ソート  
新しいトピックを投稿する トピックへ返信する  [ 11 件の記事 ] 

All times are UTC + 9 hours


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[5人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
Powered by MozillaZine.jp® Forum Software © phpBB Group , Almsamim WYSIWYG
Japanese translation principally by ocean