In diesem Artikel vervollständige ich eine Reihe von Veröffentlichungen, in denen ich über meine Erfahrungen beim Schreiben einer Web-Erweiterung für Browser sprechen wollte. Ich hatte bereits Erfahrung mit der Erstellung einer Web-Erweiterung, die von etwa 100.000 Chrome-Nutzern installiert wurde und autonom arbeitete. In dieser Artikelserie habe ich mich jedoch entschlossen, den Entwicklungsprozess der Web-Erweiterung zu untersuchen, indem ich sie eng in die Serverseite integriert habe.




Teil 1 ,
Teil 2 ,
Teil 3Geplante Aufgaben
Mit der Web-Erweiterung können Sie ein benutzerdefiniertes Skript so konfigurieren, dass sein Code nach dem Laden der Seite automatisch ausgeführt wird. Dies ist beispielsweise praktisch, wenn Sie eine Liste von Seiten desselben Typs zum Crawlen und Empfangen von Daten aus der Skriptausführung haben. Oder wenn Sie lästige Anzeigen auf einer Seite im Internet entfernen müssen, einen Code, um Ihre Aktionen auf einer Webressource zu verfolgen, den Hintergrund der Seite in dunkel zu ändern usw.
In diesem Fall ist es häufig erforderlich, im täglichen Zeitplanmodus Daten von der Seite zu empfangen. Wenn die Site beispielsweise über Wechselkurse verfügt und eine direkte Anforderung per URL das Hash-Argument schützt. Als solche Kopie können Sie die
Website der Central Bank of Europe betrachten . In diesem Fall müssen Sie die Hash-URL kennen, um die aktuellen Daten im XML-Format zu erhalten, um die aktuellen Wechselkurse zu erhalten.
Mit der Web-Erweiterung können Sie die erforderliche Häufigkeit für den Empfang von Daten über ein Skript festlegen, um Wechselkurse anzufordern. Die Web-Erweiterung akzeptiert eine Zeichenfolge im Format von Kronen als Eingabe. Um Wechselkurse im täglichen Modus zu erhalten, müssen Sie * * / 1 * * * angeben.
Aus technischer Sicht startet der Serverteil Puppeteer mit dem Hinzufügen eines Benutzerskripts zur Chromium-Browserseite. In diesem Fall stehen wir vor dem Problem des absichtlichen Herunterfahrens des Chromium-Prozesses im Laufe der Zeit, da eine Erhöhung der Anzahl der Prozesse die Gesamtleistung der Serverseite nachteilig beeinflusst. Wenn Sie das Benutzerskript im periodischen Modus ausführen möchten, um das oben genannte Problem zu lösen, müssen Sie eine Anforderung des Benutzerskripts an Puppeteer senden, um den Chromium-Prozess abzuschließen.
Nach langwierigen Tests des Implementierungsprozesses des Taskplaners wurde beschlossen, die Ausgabe der Skriptkonsole zu verfolgen. Um den Chromium-Prozess zu stoppen, muss das Benutzerskript über einen Befehl verfügen, um den Prozess im erforderlichen Codeabschnitt zu stoppen:
console.log('script is ended');
Mit diesem Befehl kann ein Benutzerskript den von Puppeteer generierten Chromium-Serverprozess schließen. Dies wird implementiert, indem das Puppenspieler-Konsolenereignis verfolgt wird:
Wenn das Benutzerskript nicht über einen solchen Befehl verfügt, muss der Timer zwangsweise beendet werden, um den Ausführungsprozess im Taskplanungsmodus abzuschließen. Dies wird auf einfache Weise mit setTimeout implementiert:
const timeLimitCron = 30; const timeout = setTimeout(async () => { if(browser) { await browser.close(); } clearTimeout(timeout); }, timeLimitCron * 1000 );
Da der Taskplaner auf der Serverseite ausgeführt wird und der Benutzer häufig eine bestimmte IP-Adresse verwenden muss, wurde eine Option zur Verwendung eines Proxyservers hinzugefügt.

Der Benutzer kann auch das neueste Nachrichtenprotokoll von der Puppenspielerkonsole herunterladen. Beispielsweise ist es praktisch, den korrekten Betrieb des Proxyservers zu überprüfen.
Tastaturkürzel
Während des Testens und Feldtests stellte sich heraus, dass es für einige Arten von Skripten nützlich ist, Hotkeys für deren Ausführung auf Webressourcen zu haben. Ein Beispiel für ein solches Skript ist Redability.js. Dieses Skript erstellt eine "saubere Ansicht", um den Inhalt der Site zu lesen. Das heißt, die js-Bibliothek analysiert die Struktur der Seite mit dem Inhalt und ermöglicht es Ihnen, mit hoher Wahrscheinlichkeit den Titel, den Autor und den Inhalt der Seite zu erhalten. Danach kann das Benutzerskript das HTML der Webressource überschreiben und dem Benutzer das Lesen in „reiner Form“ ohne unnötiges Markup, Werbung usw. ermöglichen.
Anfänglich war das Ausführen eines Benutzerskripts nur über eine Popup-Web-Erweiterung möglich, indem Sie auf die Schaltfläche "Ausführen" klicken. Diese Logik der Interaktion mit der Schnittstelle wird häufig durch Sicherheitsüberlegungen gerechtfertigt. Im obigen Beispiel können Sie den Inhalt einer Webressource jedoch nicht einfach in eine „reine Form“ bringen.
Wie oben beschrieben, können Sie mit der Web-Erweiterung über content.js mit dem DOM arbeiten. Das Fensterobjekt kann jedoch nicht zum Speichern von Parametern verwendet werden, da es kein Fensterobjekt einer geöffneten Registerkarte ist. Diese Bedingung schränkt den Betrieb der Web-Erweiterung als Objekt zum Verfolgen von Tastenanschlägen ein.
In dem zu lösenden Problem müssen die „Hotkeys“ zur Speicherung von der Web-Erweiterungsschnittstelle auf die Serverseite übertragen werden. Als nächstes erhalten Sie jedes Mal, wenn Sie eine Webressourcenseite laden, eine Liste mit „Hotkeys“ und laden ein Benutzerskript, nachdem Sie auf die richtige Kombination geklickt haben.
Hotkeys.js wird als Bibliothek für die Arbeit mit
Hotkeys verwendet.
Nach dem Empfang der Liste der Hotkeys von der Serverseite wird der folgende Code ausgeführt:
var hotKeysMap = {keys: [], id: []}; for(var i in data.response.data) { hotKeysMap.keys.push(data.response.data[i]['hotkeys']); hotKeysMap.id.push(data.response.data[i]["_id"]); } if(hotKeysMap.keys) { getScript("hotkeys.js", function() { var script = document.createElement("script"); script.setAttribute("class", "gCore-hotKeys"); script.setAttribute("data-endpoint", event.data.endPoint); script.setAttribute("data-token", event.data.token); script.setAttribute("data-userid", event.data.userId); script.innerHTML = "GChotKeys = JSON.parse(\"" + JSON.stringify(hotKeysMap).replace(/"/g, "\\\"") + "\");\n" + "hotkeys(GChotKeys.keys.join(','), function(event, handler) {" + " event.preventDefault();" + " localStorage.setItem('runHotKeysScript', GChotKeys.id[GChotKeys.keys.indexOf(handler.key)]);" + "});"; document.body.appendChild(script); }); }
Die Funktion getScript generiert HTML-Code für das Skript-Tag und schreibt ihn auf die Webressourcenseite. Somit haben wir auf jeder Seite die Möglichkeit, Tastenanschläge zu verfolgen. Wir müssen auch ein Array von Hotkeys übergeben, die mit der ID des auszuführenden Skripts übereinstimmen. Dies wird implementiert, indem HTML-Code für das Skript-Tag hinzugefügt wird, dessen Inhalt eine globale Variable zum Speichern des passenden Arrays im JSON-Format initiiert.
Es wurde bereits oben erwähnt, dass ein Kommunikationsproblem zwischen der geöffneten Seite der Webressource und dem Skript der Inhaltserweiterung extension.js der Weberweiterung besteht, mit dem das DOM bearbeitet wird. In diesem Fall können Sie auf eine einfache Technik zurückgreifen, um den Wert in localStorage zu überprüfen. Dies ist ein gemeinsames Objekt für die beiden oben genannten Interaktionspunkte.
In content.js können Sie einfach einmal pro Sekunde den localStorage-Wert überprüfen und dieselben DOM-Manipulationen ausführen wie beim Klicken auf die Schaltfläche "Ausführen" in der Popup-Web-Erweiterung.
setInterval(function() { if(localStorage.getItem('runHotKeysScript')) {
Auf diese Weise wird die „Hotkeys“ -Technik implementiert, mit der Sie schnell Benutzerskripte starten können, indem Sie die Leistung der internen Bibliothek zur Lösung praktischer Probleme nutzen.
Fazit
Während der Implementierung dieses Projekts wurden die praktischen Aufgaben des Schreibens der Integration zwischen dem auf meteor.js basierenden Serverteil und der browserübergreifenden Web-Erweiterung gelöst. Die wichtigsten Stolpersteine waren SCP und die Interaktionsprozesse zwischen den drei Komponenten des Client-Teils - der im Browser geöffneten Seite, den Skripten content.js und background.js.
Ich hoffe, dass meine Erfahrung es einfacher macht, spezialisiertere browserübergreifende Web-Erweiterungen zu schreiben.
In Zukunft ist geplant, die Web-Erweiterung zu lokalisieren und für die Community nützliche Skripte zu schreiben. Wenn der Leser eine Idee oder einen Wunsch hat, beim Schreiben solcher Benutzerskripte zu helfen, schreiben Sie bitte in private Nachrichten.