1

広告をブロックするためのクロム拡張を作成しています。これまでにすべてがかなりうまくいった。JavaScript - addEventListenerが定義されていません

  1. 無効にWebSocket
  2. 無効にconsole.log
  3. 無効にalert
  4. 無効にポップアップ(window.open)もちろん
  5. 無効にonbeforeunload

、ブロックするようになっている:私の目標はにありますこれらの機能は指定されたウェブサイトでのみ機能します。私は機能をブロックする方法を探しました。私が見つけた唯一の方法はそう、これは私の拡張機能のコードの前に実行されてから他のコードを防ぐことができます(document_startで実行されるコンテンツのスクリプトinit.jsを追加manifest.json

  1. に拡張子が使用して機能を無効にすることです誰も盗むしないと、私はそれらを無効にする前に、私の拡張子が
  2. オーバーライドブラックリストに載った機能を非サンドボックス環境にアクセスできるように、Webページにinit.jsジェクトコードから)
  3. をこれらの関数への参照を保存することができます

私はすべてをやりましたが、問題は関数をオーバーライドする方法でした。私はEcmaScript7の仕様では、は、機能がプロキシのインスタンスかどうかを検出する方法がないとわかりました。だから、私はこれらの関数をすべてproxyfiedし、期待どおりに動作します。ウェブサイトは私がこれらの機能すべてをオーバーライドしたことに気付かなかった。

しかし、それはすべての機能のために働くと期待しますaddEventListeneronbeforeunloadをブロックするには、プロキシハンドラを追加し、リスナー名がonbeforeunloadかどうかを確認するコールを追跡する必要があります。

addEventListener = new Proxy(addEventListener, { 
    apply: (f, t, args) => { 
    if(args[0] !== 'onbeforeunload'){ 
     f.apply(t, args); 
    } 
    } 
}); 

この呼び出しをフィルタリングし、onbeforeunloadイベントを設定していないだけの呼び出しを許可する必要があります。私は、次のスクリプトを書きました。しかし、それはをスローするReferenceError:addEventListenerは定義されていない。それは私をたくさん驚かせました。 addEventListenerがまだdocument_startで初期化されていないが、console.log(typeof addEventListener)がコンソールにログfunctionが記録されている可能性が高いと思われます。どのようにそれは可能ですか?

私はそれを説明できませんでした。しかし、私はそれを関数に入れようとしてから、addEventListenerがアクセス可能になるまでその関数に​​を入れようとしました(上記のコードをtry...catchでもカプセル化しました)。しかし、addEventListenerを変更すると常にReferenceErrorがスローされ、はエラーにスローされません。

また、デベロッパーコンソールやjavascript:...メソッドからもアクセスしようとしましたが、正常に動作していますが、エラーなしで変更できます。

編集

確認のために、問題becuase私がきちんと非サンドボックス(実際の)ページ環境にスクリプトを注入し、私は本当のwindowオブジェクトへのアクセス権を持って、this oneのようではありません。

+0

なぜソケットとconsole.logを無効にしますか? @DanielHerr。 –

+0

多くのウェブサイトでは、「ウェブソケット」を介して広告をイメージ:データとして転送しています。標準の 'adBlock'はそれらを決してブロックできません。だから、私は自分の拡張を作成することに決めました。 –

答えて

4

addEventListenerはグローバルではありません実際には間接的です。それはEventTarget.prototypeのプロパティです(少なくともChromeでは)。 windowはプロトタイプチェーンにEventTarget.prototypeを持ち、addEventListenerをグローバルにします。

だから、その代わりに、おおよそ(ちょうどデモのためのあなたのイベント名のチェック、なし)プロキシに必要があると思います:

const save = EventTarget.prototype.addEventListener; 
 
EventTarget.prototype.addEventListener = new Proxy(save, { 
 
    apply: function(target, thisArg, args) { 
 
    console.log("Foo!"); 
 
    return save.apply(thisArg, args); 
 
    } 
 
}); 
 
document.body.addEventListener("click", function() { 
 
    console.log("Clicked"); 
 
});
<p>....</p>

その他の注意事項:

  • イベント名はbeforeunloadで、onbeforeunloadではありません。
  • window.onbeforeunloadプロパティを再定義する必要があります(Object.definePropertyなど)。
+0

あなたはそれを行う問題に遭遇するかどうか、あるいはあなたの全体的なアプローチがうまくいくかどうかは分かりませんが(幸運なことです!)、それはあなたが 'addEventListener'についてのエラーを受けた理由です:-) –

+0

ただ一つより多くの質問。 'addEventListener'を変更すると' ReferenceError'が定義されている間にそれをスローしてアクセスできますが、それを変更することはできません。 –

+0

@jumpjet__なぜそれを得るのか分かりません。私は通常のChromeウィンドウで試してみます。ところで、私はそれ以前の 'addEventListener' *は* globalです。なぜなら' window'は 'EventTarget.prototype'から継承しているからです。 :-)しかし、 'window'のバージョンに割り当てても、どこにでも更新することはできません。 –

関連する問題