1

Ich erstelle eine Chrome-Erweiterung zum Blockieren von Anzeigen. Bis jetzt hat alles gut funktioniert. Mein Ziel ist es,JavaScript - addEventListener ist nicht definiert

  1. Disable WebSocket
  2. Disable console.log
  3. Disable alert
  4. Disable Pop-ups (window.open)
  5. Disable onbeforeunload

Natürlich ist es angeblich zu blockieren Diese Funktionen funktionieren nur auf bestimmten Websites. Ich habe gesucht, wie man eine Funktion blockiert. Was ich fand, ist, dass der einzige Weg, um eine Funktion zu deaktivieren, indem Erweiterung

ist
  1. In manifest.jsoninit.js einen Content-Skript hinzufügen, die auf document_start laufen (dies einen anderen Code verhindern wird aus der Zeit vor Code meiner Erweiterung der ausgeführt wird, so niemand kann auf diese Funktionen stehlen und speichern, bevor ich sie deaktivieren)
  2. Von init.js inject Code in die Homepage, so dass meine Erweiterung nicht-Sandbox-Umgebung
  3. Aufschalten der schwarzen Liste Funktionen zugreifen können

Ich habe alles gemacht, aber das Problem war, wie man Funktionen überschreibt. Ich fand auf EcmaScript7 Spezifikation, dass gibt es keine Möglichkeit zu erkennen, ob eine Funktion Proxy-Instanz ist oder nicht. Also habe ich jede dieser Funktionen bestätigt und es funktioniert wie erwartet. Websites konnten nicht bemerken, dass ich alle diese Funktionen überschrieben habe.

Allerdings funktioniert es für alle Funktionen erwarten addEventListener. Um onbeforeunload zu blockieren, sollte ich einen Proxy-Handler hinzufügen und Anrufe nachprüfen, ob der Listener-Name onbeforeunload ist. Ich schrieb das folgende Skript:

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

Dies sollte Anrufe filtern und nur Anrufe ermöglichen, die nicht onbeforeunload Ereignis nicht festgelegt. Es wird jedoch ReferenceError ausgelöst: addEventListener ist nicht definiert. Es hat mich sehr überrascht. Ich vermutete, dass es vielleicht, weil addEventListener ist noch nicht initialisiert um document_start, aber console.log (typeof addEventListener) Protokolle function zu Konsole. Wie ist das überhaupt möglich?

Ich konnte es nicht erklären. Allerdings habe ich versucht, es in eine Funktion zu setzen und dann auf requestAnimationFrame zu dieser Funktion, biszugänglich werden (Ich kapselte den obigen Code in try...catch auch). Aber es stellt sich heraus, dass das Modifizieren addEventListenerimmer ReferenceError wirft, während nur Zugriff darauf nie Fehler löst.

Ich habe auch versucht, es von der Entwicklerkonsole und von javascript:... Methode zuzugreifen, aber es verhält sich normal, ich kann es ohne Fehler ändern.

bearbeiten

Sicher, das Problem ist nicht wiethis one, becuase ich richtig injiziert Skript in Nicht-Sandbox (real) Seite Umgebung und ich habe Zugang zu Echt window Objekt.

+0

Warum möchten Sie Sockets und console.log deaktivieren? –

+0

@DanielHerr. Viele Websites übertragen Anzeigen als 'image: data' über' WebSockets'. Standard 'adBlock' wird niemals in der Lage sein, sie zu blockieren. Also habe ich beschlossen, meine eigene Erweiterung zu erstellen. –

Antwort

4

addEventListener ist kein globaler Eigentlich ist es, indirekt. Es ist eine Eigenschaft von EventTarget.prototype (zumindest in Chrome). window hat EventTarget.prototype in seiner Prototyp-Kette, die addEventListener eine globale macht.

Also würden Sie Proxy müssen, dass anstelle, grob (ohne Ereignisnamen zu überprüfen, damit für die Demonstration):

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>

Andere Anmerkungen:

  • Der Ereignisname ist beforeunload, nicht onbeforeunload.
  • Sie müssen die window.onbeforeunload-Eigenschaft neu definieren, um Zuweisungen zu verhindern, wahrscheinlich über Object.defineProperty.
+0

Ich habe keine Ahnung, ob Sie auf Probleme stoßen werden oder ob Ihr Gesamtansatz funktioniert (viel Glück damit!), Aber deshalb haben Sie den Fehler über 'addEventListener' bekommen ... :-) –

+0

Nur ein mehr Frage. Wie würdest du erklären, dass das Ändern von 'addEventListener' einen 'ReferenceError' auslöst, während er definiert ist und ich darauf zugreifen, aber nicht ändern kann? –

+0

@jumpjet__ Ich bin mir nicht sicher, warum Sie das bekommen würden. Ich mache es nicht, wenn ich es in einem normalen Chrome-Fenster versuche. BTW, ich habe nicht früher gedacht, 'addEventListener' * ist * global, weil' window' es von 'EventTarget.prototype' erbt. :-) Aber die Zuweisung zu 'window's Version würde es nicht ermöglichen, sie überall zu aktualisieren. –

Verwandte Themen