MozillaZine.jp フォーラム https://forums.mozillazine.jp/ |
|
リダイレクトの検知方法 https://forums.mozillazine.jp/viewtopic.php?f=26&t=7784 |
ページ 1 / 1 |
作成者: | masahal [ 2008年9月08日(月) 21:24 ] |
記事の件名: | リダイレクトの検知方法 |
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はドキュメントでないときでもドキュメントと判断してしまいます。 |
作成者: | Piro [ 2008年9月11日(木) 13:09 ] |
記事の件名: | Re: リダイレクトの検知方法 |
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メソッドに渡される引数の中に、訪問の方法(リンクをクリックしたのか、リダイレクトなのか、など)が含まれています。 |
作成者: | masahal [ 2008年9月12日(金) 02:26 ] |
記事の件名: | Re: リダイレクトの検知方法 |
すいません。ちょっとコードの使い方がわからないんですが……。 status filter をNOTIFY_ALLにすれば全ての情報が渡されると言うことなんでしょうか。 でも、その場合でもリダイレクトは検知できてないようなんですが……。 |
作成者: | あ [ 2008年9月14日(日) 01:06 ] |
記事の件名: | Re: リダイレクトの検知方法 |
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 すればいいんじゃないでしょうか。 |
作成者: | Piro [ 2008年9月14日(日) 11:54 ] |
記事の件名: | Re: リダイレクトの検知方法 |
あ さんが書きました: Piro さんが書きました: また、masahal さんのコードのように、gBrowser.addProgressListener() とした場合は Progress Filter で受け取ったものを分配する形(gBrowser は、tabbrowser 要素です)なので、やはり STATE_REDIRECTING は落とされていると思います。 tabbrowser 要素の addProgressListener ではなく、browser 要素の webProgress に対して直接 addProgressListener すればいいんじゃないでしょうか。 おおお……そんな仕様になっていたとは。 自分がやるときはいつもはTabOpenとかのイベントを拾って直接event.target.linkedBrowser.webProgress.addProgressListenerしてたので、気付いていませんでした。 説明やログをちゃんと読まないまま適当発言してすみません。>ALL |
作成者: | Piro [ 2008年9月14日(日) 12:29 ] |
記事の件名: | Re: リダイレクトの検知方法 |
このままだとゴミレスでしかないので、上のレスで少し書いた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では動作しません。 |
作成者: | masahal [ 2008年9月15日(月) 14:51 ] |
記事の件名: | Re: リダイレクトの検知方法 |
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; } } |
作成者: | あ [ 2008年9月18日(木) 01:18 ] |
記事の件名: | Re: リダイレクトの検知方法 |
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 さんが書きました: 本来取得すべきでないリダイレクトを取得してしまったりするようなので、こっちもダメっぽいです。
どういったものが本来取得すべきで、どういったものがすべきでないのでしょうか? |
作成者: | masahal [ 2008年9月25日(木) 01:50 ] |
記事の件名: | Re: リダイレクトの検知方法 |
返信遅れてすいません。 「redirectListener」の部分をあさんのコードに差し替えたところ、ちゃんとうまくいきました。 今のところ余計なものを拾ったりということはありません。 あ さんが書きました: どういったものが本来取得すべきで、どういったものがすべきでないのでしょうか?
自分の元のコードだと、例えばYahoo!ファイナンスを開くと http://rd.yahoo.co.jp/jpr_finance/tpu/n ... s/new2.gif とかが検出されてました。 |
作成者: | あ [ 2008年9月27日(土) 22:18 ] |
記事の件名: | Re: リダイレクトの検知方法 |
masahal さんが書きました: 「redirectListener」の部分をあさんのコードに差し替えたところ、ちゃんとうまくいきました。 今のところ余計なものを拾ったりということはありません。 http:// ならそこそこ行けるのではないかと思いますが、chrome:// とか resource:// とか入れられるとリダイレクト扱いになってしまうと思いますので、お気をつけください。 masahal さんが書きました: あ さんが書きました: どういったものが本来取得すべきで、どういったものがすべきでないのでしょうか? 自分の元のコードだと、例えばYahoo!ファイナンスを開くと http://rd.yahoo.co.jp/jpr_finance/tpu/n ... s/new2.gif とかが検出されてました。 それもリダイレクトであることには違いありませんから、本来取得すべきかどうかという話ではなくて、あなたの使い方に対して取得してほしいかどうかという話ですね。 「あなたの使い方」についての情報が不足していて前提条件がはっきりしない割には、前提条件が既知だったかのような書き方が見受けられます。 たとえば、遅れがあってはいけないというような前提条件は最初書かれていなかったのに、Piro さんがせっかくコードを書いてくださった後に「1秒ぐらい遅れが出るようなのでちょっと使えないようです」とか、もう少し違った書き方はないものでしょうか。 |
作成者: | masahal [ 2008年10月01日(水) 00:28 ] |
記事の件名: | Re: リダイレクトの検知方法 |
あ さんが書きました: 「あなたの使い方」についての情報が不足していて前提条件がはっきりしない割には、前提条件が既知だったかのような書き方が見受けられます。
たとえば、遅れがあってはいけないというような前提条件は最初書かれていなかったのに、Piro さんがせっかくコードを書いてくださった後に「1秒ぐらい遅れが出るようなのでちょっと使えないようです」とか、もう少し違った書き方はないものでしょうか。 すいません。以後気をつけます。 |
ページ 1 / 1 | All times are UTC + 9 hours |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |