Entwicklungshandbuch für Chrome-Plugins (Erweiterungen) (vollständige Demo)

Entwicklungshandbuch für Chrome-Plugins (Erweiterungen) (vollständige Demo)

Nachrichtenkommunikation

Messaging -Homepage: https://developer.chrome.com/extensions/messaging

Früher haben wir die fünf Arten von JS in Chrome-Plug-Ins eingeführt. Wie kommunizieren sie also miteinander? Lassen Sie uns zuerst einen Überblick über das System geben und dann die Kategorien im Detail erläutern. Was Sie wissen müssen, ist, dass Popup und Hintergrund tatsächlich als fast dasselbe angesehen werden können, da sie die gleiche zugängliche API, den gleichen Kommunikationsmechanismus haben und Domänen überqueren können.

Überblick über die gegenseitige Kommunikation

HINWEIS: - Zeigt nicht Existenz oder Sinnlosigkeit oder anhängige Überprüfung an.

Vorne geschrieben

Ich habe fast einen Monat gebraucht, um diesen Blogbeitrag zu schreiben, und habe dabei sorgfältig eine vollständige Demo geschrieben. Jeder weiß, wie schwierig es ist, einen Blog zu schreiben. Achten Sie daher beim Nachdruck darauf, die Quelle beizubehalten. Die meisten der in diesem Artikel enthaltenen Codes befinden sich in dieser Demo: https://github.com/sxei/chrome-plugin-demo. Sie können sie herunterladen und direkt ausführen.

Darüber hinaus enthält dieser Artikel viele Bilder und die Bandbreite des Bildservers ist begrenzt. Die Überwachung des Verzeichnis-Scrollings in der unteren rechten Ecke muss warten, bis alle Bilder geladen sind, bevor sie ausgelöst wird. Warten Sie also bitte geduldig, bis der Ladevorgang abgeschlossen ist.

Inhalt dieses Artikels:

Einige Screenshots der Demo:

Vorwort

Was ist ein Chrome-Plugin?

Genau genommen sollte das, worüber wir sprechen, als Chrome Extension bezeichnet werden. Ein echtes Chrome-Plug-In ist eine Browserfunktionserweiterung auf niedrigerer Ebene, für deren Entwicklung möglicherweise ein gewisses Verständnis des Browser-Quellcodes erforderlich ist. Da die Leute daran gewöhnt sind, Chrome als Plug-In zu bezeichnen, wird in diesem Artikel auch dieser Name verwendet. Die Leser sollten sich jedoch darüber im Klaren sein, dass sich das in diesem Artikel beschriebene Chrome-Plug-In tatsächlich auf eine Chrome-Erweiterung bezieht.

Das Chrome-Plug-in ist eine mit Webtechnologie entwickelte Software zur Verbesserung der Browserfunktionen. Es handelt sich eigentlich um ein komprimiertes Paket mit der Endung .crx, das aus HTML, CSS, JS, Bildern und anderen Ressourcen besteht.

Ich vermute, dass crx die Abkürzung der folgenden drei Buchstaben Chrome Extension sein könnte:

Darüber hinaus handelt es sich nicht nur um Front-End-Technologie. Chrome-Plug-Ins können auch mit in C++ geschriebenen DLL-Dynamic-Link-Bibliotheken zusammenarbeiten, um einige Funktionen auf niedrigerer Ebene (NPAPI) zu implementieren, z. B. Vollbild-Screenshots.

Aus Sicherheitsgründen unterstützen die Chrome-Browserversionen 42 und höher keine NPAPI-Plug-Ins mehr und haben diese durch das sicherere PPAPI ersetzt.

Welche Bedeutung hat es, die Entwicklung von Chrome-Plug-ins zu erlernen?

Erweitern Sie die Browserfunktionalität, erstellen Sie ganz einfach Ihren eigenen „angepassten“ Browser und vieles mehr.

Das Chrome-Plugin stellt uns viele nützliche APIs zur Verfügung, unter anderem:

  • Lesezeichensteuerung;
  • Download-Steuerung;
  • Fenstersteuerung;
  • Etikettenkontrolle;
  • Netzwerkanforderungskontrolle und Überwachung verschiedener Ereignisse;
  • Natives Menü anpassen;
  • Perfekter Kommunikationsmechanismus;
  • usw;

Warum ein Chrome-Plugin statt eines Firefox-Plugins?

  • Chrome hat einen höheren Marktanteil und wird von mehr Menschen verwendet;
  • Einfachere Entwicklung;
  • Die Anwendungsszenarien sind breiter. Firefox-Plug-Ins können nur auf Firefox ausgeführt werden, während Chrome auf allen inländischen Browsern mit Webkit-Kernel ausgeführt werden kann, z. B. 360 Speed ​​Browser, 360 Security Browser, Sogou Browser, QQ Browser usw.
  • Darüber hinaus bietet der Firefox-Browser auch eine gewisse Unterstützung für den Betrieb von Chrome-Plug-Ins.

Entwicklung und Debugging

Das Chrome-Plug-In stellt keine strengen Anforderungen an die Projektstruktur. Solange sich in diesem Verzeichnis eine manifest.json befindet, ist keine spezielle IDE erforderlich und es können normale Webentwicklungstools verwendet werden.

Sie können die Plug-In-Verwaltungsseite über das Menü oben rechts -> Weitere Tools -> Erweiterungen aufrufen oder direkt „chrome://extensions“ in die Adressleiste eingeben, um darauf zuzugreifen.

Aktivieren Sie開發者模式, um das Plugin direkt in Form eines Ordners zu laden. Andernfalls können Sie nur Dateien im .crx Format installieren. Chrome erfordert, dass Plug-Ins aus dem Chrome App Store installiert werden. Von anderen Websites heruntergeladene Plug-Ins können nicht direkt installiert werden. Daher können wir die crx Datei tatsächlich entpacken und dann direkt im Entwicklermodus laden.

Während der Entwicklung muss bei jeder Änderung am Code das Plugin neu geladen werden. Drücken Sie dazu einfach Ctrl+R auf der Plugin-Verwaltungsseite. Am besten aktualisieren Sie die Seite vorsichtshalber.

Kerneinführung

manifest.json

Dies ist die wichtigste und wesentlichste Datei eines Chrome-Plug-Ins. Sie wird zum Konfigurieren aller Plug-In-bezogenen Konfigurationen verwendet und muss im Stammverzeichnis abgelegt werden. Davon sind manifest_version , name und version wichtig, während description und icons empfohlen werden.

Nachfolgend finden Sie einige allgemeine Konfigurationselemente, alle mit chinesischen Kommentaren. Klicken Sie hier, um das vollständige Konfigurationsdokument anzuzeigen.

{
	// Die Version der Manifestdatei, diese muss geschrieben werden und muss 2 sein
	"manifest_version": 2,
	// Der Name des Plugins "name": "demo",
	//Version des Plugins "version": "1.0.0",
	// Plugin-Beschreibung "description": "Einfache Chrome-Erweiterungsdemo",
	// Symbole, es ist in Ordnung, einfach eine Größe für alle Symbole zu verwenden „Symbole“:
	{
		"16": "img/icon.png",
		"48": "img/icon.png",
		"128": "img/icon.png"
	},
	// Hintergrund-JS oder Hintergrundseite, die immer vorhanden sein wird „Hintergrund“:
	{
		// 2 Möglichkeiten zur Angabe. Wenn Sie JS angeben, wird automatisch eine Hintergrundseite generiert: "page": "background.html"
		//"Skripte": ["js/background.js"]
	},
	// In den Browsersymboleinstellungen oben rechts, browser_action, page_action, app muss „browser_action“ ausgewählt sein: 
	{
		"Standardsymbol": "img/icon.png",
		// Der Titel, wenn über das Symbol gefahren wird, optional „default_title“: „Dies ist ein Beispiel-Chrome-Plugin“,
		"default_popup": "popup.html"
	},
	// Icons, die nur angezeigt werden, wenn bestimmte Seiten geöffnet werden /*"page_action":
	{
		"Standardsymbol": "img/icon.png",
		"default_title": "Ich bin pageAction",
		"default_popup": "popup.html"
	},*/
	// Muss JS direkt in die Seite einfügen
	"Inhaltsskripte": 
	[
		{
			//"Übereinstimmungen": ["http://*/*", "https://*/*"],
			// "<all_urls>" bedeutet, dass alle Adressen übereinstimmen "matches": ["<all_urls>"],
			// Mehrere JS werden nacheinander eingefügt "js": ["js/jquery-1.8.3.js", "js/content-script.js"],
			// Sie können JS nach Belieben einfügen, aber bei CSS müssen Sie vorsichtig sein, da es den globalen Stil beeinträchtigen kann, wenn Sie nicht aufpassen "css": ["css/custom.css"],
			// Zeit für Code-Injektion, optionale Werte: „document_start“, „document_end“ oder „document_idle“, letzterer bedeutet, wenn die Seite im Leerlauf ist, der Standardwert ist „document_idle“.
			"run_at": "Dokumentstart"
		},
		// Dies dient nur zur Demonstration, dass content-script mit mehreren Regeln konfiguriert werden kann {
			"Übereinstimmungen": ["*://*/*.png", "*://*/*.jpg", "*://*/*.gif", "*://*/*.bmp"],
			"js": ["js/Bildinhaltsgröße anzeigen.js"]
		}
	],
	// Berechtigungsanwendung „permissions“:
	[
		"contextMenus", // Rechtsklickmenü "tabs", // Tags "notifications", // Benachrichtigungen "webRequest", // Web-Anfrage "webRequestBlocking",
		"storage", // Lokaler Speicher des Plugins "http://*/*", // Websites auf die über executeScript oder insertCSS zugegriffen werden kann "https://*/*" // Websites auf die über executeScript oder insertCSS zugegriffen werden kann ],
	// Liste der Plugin-Ressourcen, auf die von normalen Seiten direkt zugegriffen werden kann. Wenn sie nicht festgelegt sind, können sie nicht direkt aufgerufen werden "web_accessible_resources": ["js/inject.js"],
	// Plugin-Homepage, das ist sehr wichtig, verschwenden Sie diesen kostenlosen Werbeplatz nicht "homepage_url": "https://www.baidu.com",
	// Überschreibe die Standardseite des Browsers „chrome_url_overrides“:
	{
		// Überschreibe die standardmäßige neue Tab-Seite des Browsers „newtab“: „newtab.html“
	},
	// So schreiben Sie die Plugin-Konfigurationsseite vor Chrome 40 "options_page": "options.html",
	// So schreiben Sie die Plugin-Konfigurationsseite in Chrome 40 und höher. Wenn Sie beide schreiben, erkennt die neue Version von Chrome nur die letztere „options_ui“:
	{
		"Seite": "Optionen.html",
		// Fügen Sie einige Standardstile hinzu. Es wird empfohlen, "chrome_style" zu verwenden: true
	},
	// Tragen Sie ein Schlüsselwort in die Adressleiste ein, um Suchvorschläge bereitzustellen. Es kann nur ein Schlüsselwort festgelegt werden: "omnibox": { "keyword" : "go" },
	// Standardsprache "default_locale": "zh_CN",
	// devtools-Seiteneintrag, beachten Sie, dass er nur auf eine HTML-Datei verweisen kann, nicht auf eine JS-Datei "devtools_page": "devtools.html"
}

Inhaltsskripte

Die sogenannten Inhaltsskripte sind eigentlich eine Art Skripteinfügung in die Seite im Chrome-Plug-In (obwohl es Skript genannt wird, kann es tatsächlich CSS enthalten). Mithilfe von content-scripts können wir JS und CSS ganz einfach durch Konfiguration in die angegebene Seite einfügen (wenn eine dynamische Einfügung erforderlich ist, beachten Sie bitte Folgendes). Die häufigsten Beispiele sind: Werbeblockierung, Seiten-CSS-Anpassung usw.

Beispielkonfiguration:

{
	// Muss JS direkt in die Seite einfügen
	"Inhaltsskripte": 
	[
		{
			//"Übereinstimmungen": ["http://*/*", "https://*/*"],
			// "<all_urls>" bedeutet, dass alle Adressen übereinstimmen "matches": ["<all_urls>"],
			// Mehrere JS werden nacheinander eingefügt "js": ["js/jquery-1.8.3.js", "js/content-script.js"],
			// Sie können JS nach Belieben einfügen, aber bei CSS müssen Sie vorsichtig sein, da es den globalen Stil beeinträchtigen kann, wenn Sie nicht aufpassen "css": ["css/custom.css"],
			// Zeit für Code-Injektion, optionale Werte: „document_start“, „document_end“ oder „document_idle“, letzterer bedeutet, wenn die Seite im Leerlauf ist, der Standardwert ist „document_idle“.
			"run_at": "Dokumentstart"
		}
	],
}

Beachten Sie, dass der folgende Code nicht funktioniert, wenn run_at nicht als document_start angegeben ist (der Standard ist document_idle ):

document.addEventListener('DOMContentLoaded', Funktion()
{
	console.log('Ich wurde hingerichtet!');
});

content-scripts und die Originalseite teilen sich das DOM, aber nicht das JS. Wenn Sie auf das Seiten-JS (z. B. eine JS-Variable) zugreifen möchten, können Sie dies nur über injected js tun. content-scripts können auf die meisten Elemente chrome.xxx.api nicht zugreifen, mit Ausnahme der folgenden 4:

  • chrome.extension(getURL, inIncognitoContext, letzterFehler, beiAnfrage, sendeAnfrage)
  • chrom.i18n
  • chrome.runtime(Verbinden, Manifest abrufen, URL abrufen, ID, beiVerbindung, beiNachricht, Nachricht senden)
  • Chrome-Speicher

Seien Sie nicht pessimistisch, wenn Sie das sehen. Diese APIs reichen in den meisten Fällen aus. Wenn Sie wirklich andere APIs aufrufen müssen, können Sie auch die Kommunikation nutzen, um sich beim Aufruf vom Hintergrund helfen zu lassen (mehr zur Kommunikation später).

Nun, das Chrome-Plug-In stellt uns eine solch leistungsstarke JS-Injektionsfunktion zur Verfügung. Der Rest besteht darin, Ihrer Fantasie freien Lauf zu lassen und mit dem Browser zu spielen.

Hintergrund

Der Hintergrund (übersetzen wir es so) ist eine permanente Seite mit dem längsten Lebenszyklus aller Seitentypen im Plug-In. Sie wird geöffnet, wenn der Browser geöffnet wird, und geschlossen, wenn der Browser geschlossen wird. Daher wird der globale Code, der ständig ausgeführt werden muss und beim Start ausgeführt wird, normalerweise im Hintergrund platziert.

Der Hintergrund verfügt über sehr hohe Berechtigungen und kann fast alle Chrome-Erweiterungs-APIs aufrufen (außer Devtools) und er kann ohne Einschränkungen auf alle Websites domänenübergreifend zugreifen, das heißt, er kann auf alle Websites domänenübergreifend zugreifen, ohne dass die andere Partei CORS festlegen muss.

Nach dem Testen ist dies nicht nur im Hintergrund der Fall, sondern auf allen Webseiten, die direkt über chrome-extension://id/xx.html geöffnet werden, können ohne Einschränkungen domänenübergreifend verwendet werden.

In der Konfiguration kann background über page eine Webseite oder über scripts “ direkt ein JS angeben. Chrome generiert automatisch eine Standardwebseite für dieses JS:

{
	// Hintergrund-JS oder Hintergrundseite, die immer vorhanden sein wird „Hintergrund“:
	{
		// 2 Möglichkeiten zur Angabe. Wenn Sie JS angeben, wird automatisch eine Hintergrundseite generiert: "page": "background.html"
		//"Skripte": ["js/background.js"]
	},
}

Es ist zu beachten, dass Sie zwar die Hintergrundseite direkt über chrome-extension://xxx/background.html öffnen können, die von Ihnen geöffnete Hintergrundseite jedoch nicht mit der Seite identisch ist, die tatsächlich im Hintergrund ausgeführt wird. Mit anderen Worten: Sie können unzählige background.html öffnen, aber es gibt nur eine, die tatsächlich im Hintergrund bleibt, und Sie können ihre Benutzeroberfläche nie sehen, sondern nur ihren Code debuggen.

Veranstaltungsseiten

Hier möchte ich event-pages vorstellen. Was ist das? Da der Lebenszyklus des Hintergrunds zu lang ist, kann eine lange Einbindung des Hintergrunds die Leistung beeinträchtigen. Aus diesem Grund hat Google event-pages erstellt. Der einzige Unterschied zwischen event-pages und background in der Konfigurationsdatei ist ein zusätzlicher persistent Parameter:

{
	"Hintergrund":
	{
		"Skripte": ["event-page.js"],
		"persistent": falsch
	},
}

Sein Lebenszyklus ist: geladen, wenn benötigt, und geschlossen, wenn inaktiv. Was bedeutet es, wenn es benötigt wird? Beispielsweise die Erstinstallation, das Update des Plugins, das Senden von Nachrichten durch Inhaltsskripts usw.

Neben den Änderungen in den Konfigurationsdateien gibt es auch einige kleinere Änderungen im Code. Ich muss sie mir nur kurz ansehen. Im Allgemeinen wird der Hintergrund nicht viel Leistung verbrauchen.

aufpoppen

popup ist ein kleines Fenster einer Webseite, das sich öffnet, wenn Sie auf browser_action oder page_action Aktionssymbol klicken. Es schließt sich sofort, wenn der Fokus die Webseite verlässt. Es wird im Allgemeinen für einige temporäre Interaktionen verwendet.

popup kann jeden gewünschten HTML-Inhalt enthalten und wird automatisch in der Größe angepasst. Sie können die Popup-Seite über das Feld default_popup angeben oder setPopup() aufrufen.

Konfigurationsmethode:

{
	"Browseraktion":
	{
		"Standardsymbol": "img/icon.png",
		// Der Titel, wenn über das Symbol geschwebt wird, optional „default_title“: „Dies ist ein Beispiel-Chrome-Plugin“,
		"default_popup": "popup.html"
	}
} 

Es ist wichtig zu beachten, dass der Lebenszyklus einer Popup-Seite im Allgemeinen sehr kurz ist, da ein Popup durch Klicken auf ein Symbol geöffnet und sofort geschlossen wird, wenn der Fokus entfernt wird. Code, der lange ausgeführt werden muss, sollte niemals in ein Popup geschrieben werden.

In Bezug auf Berechtigungen ist es dem Hintergrund sehr ähnlich. Der größte Unterschied zwischen ihnen ist der Unterschied im Lebenszyklus. Im Popup können Sie das Hintergrundfensterobjekt direkt über chrome.extension.getBackgroundPage() abrufen.

injiziertes Skript

injected-script ist hier ein Name, den ich ihm gegeben habe und der sich auf eine Art JS bezieht, das durch DOM-Manipulation in die Seite injiziert wird. Warum sollten wir diese Art von JS separat besprechen? Oder warum müssen wir JS auf diese Weise einfügen?

Dies liegt daran, dass content-script einen großen „Fehler“ aufweist, nämlich nicht auf das JS auf der Seite zugreifen kann. Obwohl es das DOM bedienen kann, kann das DOM es nicht aufrufen, d. h. es ist unmöglich, den Code im content-script durch Binden von Ereignissen im DOM aufzurufen (einschließlich des direkten Schreibens von onclick und addEventListener ). „Hinzufügen einer Schaltfläche zur Seite und Aufrufen der Erweiterungs-API des Plug-Ins“ ist jedoch eine sehr häufige Anforderung. Was sollen wir also tun? Genau darum geht es in diesem Abschnitt.

Im content-script wird ein inject-script Codebeispiel über DOM in die Seite eingefügt:

// JS in die Seite einfügen
Funktion injectCustomJs(jsPath)
{
	jsPath = jsPath || 'js/inject.js';
	var temp = document.createElement('Skript');
	temp.setAttribute('Typ', 'Text/Javascript');
	// Die erhaltene Adresse ähnelt: chrome-extension://ihcokhadfjfchaeagdoclpnjdiokfakg/js/inject.js
	temp.src = chrome.extension.getURL(jsPath);
	temp.onload = Funktion ()
	{
		// Es sieht auf der Seite nicht gut aus, entfernen Sie es nach der Ausführung this.parentNode.removeChild(this);
	};
	Dokument.Kopf.AnhängenUntergeordnetesElement(temp);
}

Meinen Sie, das ist alles? Wenn Sie es ausführen, wird der folgende Fehler angezeigt:

Laden der Chrome-Erweiterung://efbllncjkjiijkppagepehoekjojdclc/js/inject.js wird verweigert. Ressourcen müssen im Manifestschlüssel „web_accessible_resources“ aufgeführt sein, um von Seiten außerhalb der Erweiterung geladen zu werden.

Das bedeutet, wenn Sie direkt auf die Ressourcen im Plugin im Web zugreifen möchten, müssen Sie dies explizit deklarieren. Fügen Sie der Konfigurationsdatei Folgendes hinzu:

{
	// Liste der Plugin-Ressourcen, auf die von normalen Seiten direkt zugegriffen werden kann. Wenn sie nicht festgelegt sind, können sie nicht direkt aufgerufen werden "web_accessible_resources": ["js/inject.js"],
}

Wie inject-script den Code im content-script aufruft, werde ich später in einem speziellen Kapitel zur Nachrichtenkommunikation ausführlich vorstellen.

Homepage-URL

Die Homepage-Einstellungen des Entwicklers oder Plugins werden im Allgemeinen an den folgenden zwei Stellen angezeigt:

8 Anzeigemodi des Chrome-Plug-Ins

BrowserAction (obere rechte Ecke des Browsers)

Durch Konfigurieren von browser_action können Sie der oberen rechten Ecke des Browsers ein Symbol hinzufügen. Eine browser_action kann ein Symbol, einen tooltip , ein badge und ein popup enthalten.

Die Beispielkonfiguration sieht wie folgt aus:

"Browseraktion":
{
	"Standardsymbol": "img/icon.png",
	"default_title": "Dies ist ein Beispiel-Plug-in für Chrome",
	"default_popup": "popup.html"
}

Symbol

Für das browser_action -Symbol wird empfohlen, ein Bild mit einer Breite und Höhe von 19 Pixeln zu verwenden. Größere Symbole werden verkleinert. Das Format ist beliebig, im Allgemeinen wird PNG empfohlen. Es kann über das Feld default_icon im Manifest oder durch Aufrufen der Methode setIcon() konfiguriert werden.

Tooltip

Ändern Sie das Feld default_title im browser_action Manifest oder rufen Sie setTitle() auf.

Abzeichen

Das sogenannte badge dient dazu, auf dem Symbol einen Text anzuzeigen, der zum Aktualisieren kleiner erweiterter Statusinformationen verwendet werden kann. Da der Platz für das Badge begrenzt ist, werden maximal 4 Zeichen unterstützt (4 für Englisch und 2 für Chinesisch). Das Badge kann nicht über die Konfigurationsdatei angegeben werden und muss über Code implementiert werden. Um den Badge-Text und die Badge-Farbe festzulegen, verwenden Sie setBadgeText() bzw. setBadgeBackgroundColor() .

chrome.browserAction.setBadgeText({text: 'neu'});
chrome.browserAction.setBadgeBackgroundColor({color: [255, 0, 0, 255]});

Wirkung:

pageAction (rechte Seite der Adressleiste)

Bei der sogenannten pageAction handelt es sich um ein Icon, das nur beim Öffnen bestimmter Seiten angezeigt wird. Der größte Unterschied zur browserAction besteht darin, dass die eine immer und die andere nur in bestimmten Situationen angezeigt wird.

Es ist zu beachten, dass frühere Versionen von Chrome pageAction ganz rechts in der Adressleiste platzierten. Wenn Sie mit der linken Maustaste darauf klicken, wird ein Popup-Fenster geöffnet, und wenn Sie mit der rechten Maustaste darauf klicken, wird ein Standardoptionsmenü angezeigt:

Die neue Version von Chrome hat diese Strategie geändert. PageAction wird wie die normale BrowserAction in der oberen rechten Ecke des Browsers platziert, ist jedoch grau, wenn es nicht leuchtet, und bunt, wenn es leuchtet. Wenn es grau ist, werden Optionen angezeigt, egal ob Sie mit der linken oder rechten Maustaste klicken:

Ich habe nicht im Detail untersucht, in welcher Version die Änderung begann, aber ich weiß, dass es in v50.0 noch Ersteres war und in v58.0 auf Letzteres geändert wurde.

Nach der Anpassung können wir pageAction einfach als browserAction betrachten, die ausgegraut werden kann.

  • chrome.pageAction.show(tabId) zeigt das Symbol an;
  • chrome.pageAction.hide(tabId) verbirgt das Symbol;

Beispiel (das Symbol wird nur angezeigt, wenn Baidu geöffnet ist):

// manifest.json
{
	"Seitenaktion":
	{
		"Standardsymbol": "img/icon.png",
		"default_title": "Ich bin pageAction",
		"default_popup": "popup.html"
	},
	"Berechtigungen": ["deklarativer Inhalt"]
}

// Hintergrund.js
chrome.runtime.onInstalled.addListener(Funktion(){
	chrome.declarativeContent.onPageChanged.removeRules(undefiniert, Funktion(){
		chrome.declarativeContent.onPageChanged.addRules([
			{
				Bedingungen: [
					// Erst wenn Baidu geöffnet wird, wird pageAction angezeigt
					neues chrome.declarativeContent.PageStateMatcher({pageUrl: {urlContains: 'baidu.com'}})
				],
				Aktionen: [neuer chrome.declarativeContent.ShowPageAction()]
			}
		]);
	});
});

Effektbild:

Rechtsklickmenü

Durch die Entwicklung eines Chrome-Plug-Ins können Sie das Rechtsklickmenü des Browsers anpassen, hauptsächlich über chrome.contextMenus . Das Rechtsklickmenü kann in verschiedenen Kontexten erscheinen, z. B. auf normalen Seiten, in ausgewähltem Text, Bildern, Links usw. Wenn im selben Plug-In mehrere Menüs definiert sind, kombiniert Chrome diese automatisch zu einem sekundären Menü, das nach dem Plug-In benannt ist, und zwar wie folgt:

Das einfachste Rechtsklickmenü-Beispiel

// manifest.json
{"Berechtigungen": ["Kontextmenüs"]}

// Hintergrund.js
chrome.contextMenus.create({
	Titel: "Rechtsklickmenü testen",
	onclick: function(){alert('Sie haben auf das Rechtsklickmenü geklickt!');}
});

Wirkung:

Rechtsklick-Baidu-Suche hinzufügen

// manifest.json
{"Berechtigungen": ["Kontextmenüs", "Registerkarten"]}

// Hintergrund.js
chrome.contextMenus.create({
	Titel: „Verwenden Sie Baidu zum Suchen: %s“, // %s zeigt den ausgewählten Text an Kontexte: [„Auswahl“], // Dieses Rechtsklickmenü wird nur angezeigt, wenn ein Text ausgewählt ist onclick: Funktion (Parameter)
	{
		// Beachten Sie, dass location.href nicht verwendet werden kann, da location ein Fensterobjekt ist, das zum Hintergrund gehört chrome.tabs.create({url: 'https://www.baidu.com/s?ie=utf-8&wd=' + encodeURI(params.selectionText)});
	}
});

Die Wirkung ist wie folgt:

Syntax

Hier sind nur einige gängige. Die vollständige API finden Sie unter: https://developer.chrome.com/extensions/contextMenus

chrome.contextMenus.create({
	Typ: „normal“, // Typ, optional: [„normal“, „Kontrollkästchen“, „Radio“, „Trennzeichen“], Standard normal
	Titel: 'Menüname', // Der angezeigte Text, es sei denn, der Typ ist "Trennzeichen", dieser Parameter ist erforderlich. Wenn der Typ "Auswahl" ist, können Sie %s verwenden, um den ausgewählten Text anzuzeigen Kontexte: ['Seite'], // Kontext, optional: ["alles", "Seite", "Rahmen", "Auswahl", "Link", "bearbeitbar", "Bild", "Video", "Audio"], Standardseite
	onclick: function(){}, // Methode, die beim Klicken ausgelöst wird parentId: 1, // ID des übergeordneten Menüelements des Rechtsklickmenüelements. Durch die Angabe eines übergeordneten Menüelements wird dieses Menüelement zu einem Untermenü des übergeordneten Menüelements. documentUrlPatterns: 'https://*.baidu.com/*' // Dieses Rechtsklickmenü nur auf bestimmten Seiten anzeigen});
// Ein Menüelement löschen chrome.contextMenus.remove(menuItemId);
// Alle benutzerdefinierten Rechtsklickmenüs löschen chrome.contextMenus.removeAll();
// Ein Menüelement aktualisieren chrome.contextMenus.update(menuItemId, updateProperties);

überschreiben (eine bestimmte Seite überschreiben)

Mithilfe der override -Seite können Sie bestimmte Seiten des Standardbrowsers von Chrome durch von der Erweiterung bereitgestellte Seiten ersetzen.

Die Erweiterung kann folgende Seiten ersetzen:

  • Verlauf: Besuchte Seiten, wenn Sie im Menü „Extras“ auf „Verlauf“ klicken oder „chrome://history“ direkt in die Adressleiste eingeben
  • Neue Registerkarte: Die Seite, die Sie besuchen, wenn Sie eine neue Registerkarte erstellen oder einfach „chrome://newtab“ in die Adressleiste eingeben.
  • Lesezeichen: Browser-Lesezeichen oder direkt eingeben chrome://bookmarks

Beachten:

  • Eine Erweiterung kann nur eine Seite ersetzen;
  • Es ist kein Ersatz für die neue Registerkarte eines Inkognito-Fensters;
  • Webseiten müssen einen Titel haben. Andernfalls sehen Benutzer möglicherweise die URL der Webseite, was zu Verwirrung führen kann.

Die folgenden Screenshots zeigen die standardmäßige neue Registerkarte und die durch die Erweiterung ersetzte neue Registerkarte.

Code (beachten Sie, dass ein Plugin nur eine Standardseite ersetzen kann, das Folgende dient nur zur Demonstration):

"chrome_url_overrides":
{
	"newtab": "newtab.html",
	"Geschichte": "Geschichte.html",
	"Lesezeichen": "Lesezeichen.html"
}

Entwicklertools

Vorheizen

Wer Vue verwendet hat, dürfte diese Art von Plug-In gesehen haben:

Ja, Chrome erlaubt es Plugins, Entwicklertools (Devtools) zu manipulieren, hauptsächlich auf folgende Weise:

  • Passen Sie ein oder mehrere Bedienfelder auf derselben Ebene wie Elements , Console , Sources “ usw. an.
  • Passen Sie die Seitenleiste an. Derzeit können Sie nur die Seitenleiste des Elements anpassen.

Schauen wir uns zunächst zwei einfache Demo-Screenshots an, benutzerdefinierte Bedienfelder (um festzustellen, ob auf der aktuellen Seite jQuery verwendet wird):

Passen Sie die Seitenleiste an (alle Bilder der aktuellen Seite abrufen):

Einführung in die devtools-Erweiterung

Homepage: https://developer.chrome.com/extensions/devtools

Hier ist ein offizielles Bild:

Jedes Mal, wenn ein Entwicklertoolfenster geöffnet wird, wird eine Instanz der Devtools-Seite erstellt. Wenn das F12-Fenster geschlossen wird, wird auch die Seite geschlossen, sodass der Lebenszyklus der Devtools-Seite mit dem Devtools-Fenster übereinstimmt. Die DevTools-Seite kann auf eine Reihe einzigartiger DevTools API und eine begrenzte Anzahl von Erweiterungs-APIs zugreifen. Auf diese Reihe einzigartiger DevTools API kann nur von der DevTools-Seite aus zugegriffen werden, nicht vom Hintergrund aus. Zu diesen APIs gehören:

  • chrome.devtools.panels : Panel-bezogen;
  • chrome.devtools.inspectedWindow : Informationen zum überprüften Fenster abrufen.
  • chrome.devtools.network : Informationen zu Netzwerkanforderungen abrufen;

Die meisten Erweiterungs-APIs können nicht direkt von der DevTools -Seite aufgerufen werden, aber sie können chrome.extension und chrome.runtime wie content-script direkt aufrufen. Sie können auch mithilfe der Nachrichteninteraktion wie content-script mit der Hintergrundseite kommunizieren.

Beispiel: Erstellen einer Devtools-Erweiterung

Um ein Plug-In für die Entwicklertools zu entwickeln, müssen Sie zunächst Folgendes in der Manifestdatei deklarieren:

{
	// Kann nur auf eine HTML-Datei verweisen, nicht auf eine JS-Datei "devtools_page": "devtools.html"
}

Diese devtools.html enthält normalerweise nichts, führen Sie also einfach ein js ein:

<!DOCTYPE html>
<html>
<Kopf></Kopf>
<Text>
	<script type="text/javascript" src="js/devtools.js"></script>
</body>
</html>

Es ist ersichtlich, dass der eigentliche Code devtools.js ist und die HTML-Datei „redundant“ ist, sodass ich mich hier ein wenig gefangen fühle. Warum können Sie devtools_page JS nicht direkt angeben?

Schauen wir uns den Code von devtools.js an:

// Erstellen Sie ein benutzerdefiniertes Panel. Das gleiche Plug-In kann mehrere benutzerdefinierte Panels erstellen. // Die Parameter sind: Paneltitel, Symbol (eigentlich gibt es keinen Platz, um es anzuzeigen), zu ladende Seite, Rückruf nach erfolgreichem Laden chrome.devtools.panels.create('MyPanel', 'img/icon.png', 'mypanel.html', function(panel)
{
	console.log('Benutzerdefiniertes Panel erfolgreich erstellt!'); // Beachten Sie, dass dieses Protokoll normalerweise nicht sichtbar ist});

// Erstellen Sie eine benutzerdefinierte Seitenleiste chrome.devtools.panels.elements.createSidebarPane("Bilder", function(sidebar)
{
	// sidebar.setPage('../sidebar.html'); // Eine zu ladende Seite angeben sidebar.setExpression('document.querySelectorAll("img")', 'Alle Bilder'); // Durch Ausdruck angeben //sidebar.setObject({aaa: 111, bbb: 'Hallo Welt!'}); // Anzeige eines Objekts direkt festlegen});

Die Wirkung von setPage:

Der folgende Screenshot zeigt den Code:

// jQuery erkennen
document.getElementById('check_jquery').addEventListener('klicken', function()
{
	// Der Zugriff auf das DOM der untersuchten Seite erfordert die Verwendung von inspectedWindow
	// Einfaches Beispiel: Überprüfen Sie, ob die zu überprüfende Seite jQuery verwendet
	chrome.devtools.inspectedWindow.eval("jQuery.fn.jquery", Funktion(Ergebnis, isException)
	{
		var html = '';
		if (isException) html = 'Die aktuelle Seite verwendet kein jQuery. ';
		sonst html = 'Die aktuelle Seite verwendet jQuery, die Version ist:' + result;
		Alarm (HTML);
	});
});

//Öffnen Sie ein Ressourcendokument.getElementById('open_resource').addEventListener('click', function()
{
	chrome.devtools.inspectedWindow.eval("window.location.href", Funktion(Ergebnis, istAusnahme)
	{
		chrome.devtools.panels.openResource(Ergebnis, 20, Funktion()
		{
			console.log('Ressource erfolgreich geöffnet!');
		});
	});
});

//Element überprüfen document.getElementById('test_inspect').addEventListener('click', function()
{
	chrome.devtools.inspectedWindow.eval("inspect(document.images[0])", Funktion(Ergebnis, istAusnahme){});
});

// Alle Ressourcen abrufen document.getElementById('get_all_resources').addEventListener('click', function()
{
	chrome.devtools.inspectedWindow.getResources(Funktion(Ressourcen)
	{
		Alarm (JSON.stringify (Ressourcen));
	});
});

Tipps zur Fehlerbehebung

Wenn Sie den Code auf der Devtools-Seite ändern, müssen Sie auf der Seite „chrome://extensions“ Ctrl+R drücken, um die Erweiterung neu zu laden, und anschließend die Entwicklertools schließen und erneut öffnen, ohne die Seite zu aktualisieren (und das Aktualisieren der Seite ohne Aktualisieren der Entwicklertools hat keine Wirkung).

Da devtools selbst eine Entwicklertoolseite ist, gibt es fast keine Möglichkeit, sie direkt zu debuggen. Das direkte Öffnen der Seite über chrome-extension://extid/devtools.html" führt definitiv zu Fehlern, da die entsprechenden speziellen APIs nicht unterstützt werden. Sie können nur einige Methoden schreiben, um diese Fehler zu blockieren und sie nach dem Debuggen freizugeben.

Option (Optionsseite)

Die sogenannte options ist die Einstellungsseite des Plug-Ins. Es gibt zwei Eingänge, einer ist das Menü "Optionen", wenn Sie mit der rechten Maustaste auf das Symbol klicken, und der andere ist die Plug-In-Verwaltungsseite:

Vor Chrome 40 unterschied sich die Optionsseite nicht von anderen normalen Seiten, nach Chrome 40 gab es jedoch einige Änderungen.

Schauen wir uns zunächst die alte Version der Optionen an:

{
	// So schreiben Sie die Plugin-Konfigurationsseite vor Chrome 40 "options_page": "options.html",
}

Der Inhalt dieser Seite bleibt Ihnen überlassen. Nach der Konfiguration wird auf der Plug-In-Verwaltungsseite ein選項angezeigt. Wenn Sie darauf klicken, wird eine Webseite geöffnet. Es gibt nicht viel zu sagen.

Wirkung:

Schauen wir uns die neue Version von optionsV2 an:

{
	"Optionen_UI":
	{
    	"Seite": "Optionen.html",
		// Fügen Sie einige Standardstile hinzu. Es wird empfohlen, "chrome_style" zu verwenden: true
	},
}

Wir haben den Code von options.html nicht geändert, sondern nur die Konfigurationsdatei geändert. Der Effekt ist wie folgt:

Sieht es nicht groß und majestätisch aus?

Einige Anmerkungen:

  • Aus Kompatibilitätsgründen wird empfohlen, beide Methoden zu schreiben. Wenn beide geschrieben sind, liest Chrome 40 und höher standardmäßig die neue Version.
  • Alarm kann in der neuen Version der Optionen nicht verwendet werden;
  • Es wird empfohlen, chrome.storage zur Datenspeicherung zu verwenden, da es automatisch mit dem Benutzer synchronisiert wird.

Omnibox

omnibox ist eine Möglichkeit, Benutzern Suchvorschläge zu unterbreiten. Schauen wir uns ein gif an, um zu verstehen, was das ist:

Registrieren Sie ein Schlüsselwort, um die Suchvorschlagsschnittstelle des Plugins auszulösen, und dann können Sie damit machen, was Sie wollen.

Zunächst sieht die Konfigurationsdatei wie folgt aus:

{
	// Tragen Sie ein Schlüsselwort in die Adressleiste ein, um Suchvorschläge bereitzustellen. Es kann nur ein Schlüsselwort festgelegt werden: "omnibox": { "keyword" : "go" },
}

Registrieren Sie dann das Listener-Ereignis in background.js :

// Omnibox-Demo chrome.omnibox.onInputChanged.addListener((text, suggest) => {
	console.log('inputChanged: ' + text);
	wenn(!text) zurückgeben;
	wenn(text == 'Schönheit') {
		vorschlagen([
			{content: '中国' + text, description: 'Suchen Sie nach „chinesischen Schönheiten“? '},
			{content: '日本' + text, description: 'Suchen Sie nach „japanischen Schönheiten“? '},
			{content: 'Thailand' + text, description: 'Suchen Sie nach „thailändischen Schönheiten oder Ladyboys“? '},
			{content: '韩国' + text, description: 'Suchen Sie nach „koreanischen Schönheiten“? '}
		]);
	}
	sonst wenn(Text == 'Weibo') {
		vorschlagen([
			{Inhalt: 'Sina' + Text, Beschreibung: 'Sina' + Text},
			{Inhalt: 'Tencent' + Text, Beschreibung: 'Tencent' + Text},
			{Inhalt: 'Sohu' + Text, Beschreibung: 'Suche' + Text},
		]);
	}
	anders {
		vorschlagen([
			{Inhalt: ‚Baidu-Suche‘ + Text, Beschreibung: ‚Baidu-Suche‘ + Text},
			{Inhalt: 'Google-Suche' + Text, Beschreibung: 'Google-Suche' + Text},
		]);
	}
});

// Wird ausgelöst, wenn der Benutzer Schlüsselwortvorschläge erhält chrome.omnibox.onInputEntered.addListener((text) => {
    console.log('inputEntered: ' + text);
	wenn(!text) zurückgeben;
	var href = '';
    if(text.endsWith('Suche')) href = 'http://image.baidu.com/search/index?tn=baiduimage&ie=utf-8&word=' + text;
	sonst wenn (text.startsWith('Baidu-Suche')) href = 'https://www.baidu.com/s?ie=UTF-8&wd=' + text.replace('Baidu-Suche', '');
	sonst wenn (text.startsWith('Google-Suche')) href = 'https://www.google.com.tw/search?q=' + text.replace('Google-Suche', '');
	sonst href = 'https://www.baidu.com/s?ie=UTF-8&wd=' + Text;
	öffneUrlCurrentTab(href);
});
// Aktuelle Tab-ID abrufen
Funktion getCurrentTabId(Rückruf)
{
	chrome.tabs.query({aktiv: true, aktuellesFenster: true}, Funktion(Tabs)
	{
		wenn (Rückruf) Rückruf (Tabs.Länge? Tabs[0].id: null);
	});
}

//Öffnen Sie einen Link in der aktuellen Registerkarte Funktion openUrlCurrentTab(url)
{
	getCurrentTabId(tabId => {
		chrome.tabs.update(tabId, {url: url});
	})
}

Desktop-Benachrichtigungen

Chrome liefert eine chrome.notifications API für Plug-Ins, chrome.notifications Desktop- Notification zu verschieben.

Im Hintergrund JS, unabhängig davon, ob Sie chrome.notifications oder Notification müssen Sie keine Berechtigungen beantragen (die HTML5 -Methode erfordert die Beantragung von Berechtigungen), können Sie es direkt verwenden.

Die einfachste Benachrichtigung:

Code:

chrome.notifications.create (null, {{
	Typ: 'grundlegend',
	iconurl: 'img/icon.png',
	Titel: 'Dies ist der Titel',
	Nachricht: 'Sie haben gerade auf das Menü mit dem benutzerdefinierten Klick geklickt! '
});

Die Benachrichtigungsstile können sehr reich sein:

Dies wurde nicht ausführlich untersucht. Sie können die offizielle Dokumentation lesen, wenn Sie sie benötigen.

Vergleich von 5 Arten von JS

Chrome Plug-In JS kann hauptsächlich in diese fünf Kategorien unterteilt werden: injected script , content-script , popup js , background js und devtools js .

Erlaubnisvergleich

JS -Typen Zugängliche API DOM -Zugriff JS -Zugriffsstatus Direkte Cross-Domäne
injiziertes Skript Es unterscheidet sich nicht von normaler JS und kann keine erweiterten APIs zugreifen. Kann zugreifen Kann zugreifen Kippen
Inhaltskript Es können nur auf einige APIs wie Erweiterung und Laufzeit zugegriffen werden Kann zugreifen Kippen Kippen
Popup JS Zugang zu den meisten APIs, mit Ausnahme der Devtools -Serie Nicht direkt zugänglich Kippen Kann
Hintergrund Zugang zu den meisten APIs, mit Ausnahme der Devtools -Serie Nicht direkt zugänglich Kippen Kann
devtools js Nur einige APIs wie Devtools, Erweiterung, Laufzeit usw. können zugegriffen werden Kann Kann Kippen

Vergleich der Debugging -Methoden

JS -Typ Debugging -Modus Bildbeschreibung
injiziertes Skript Drücken Sie einfach den normalen F12 Zu faul, um Screenshots zu machen
Content-Skript Öffnen Sie die Konsole und den Schalter, wie in der Abbildung gezeigt
Popup-Js Klicken Sie mit der rechten Maustaste auf die Popup -Seite, um die Elemente zu inspizieren
Hintergrund Klicken Sie auf der Seite "Plugin Management" auf die Seite "Hintergrund"
Devtools-Js Es wurde noch keine wirksame Methode gefunden -
injiziertes Skript Content-Skript Popup-Js Hintergrund-Js
injiziertes Skript - Fenster.PostMessage - -
Content-Skript Fenster.PostMessage - Chrome.Runtime.SendMessage Chrome.Runtime.Connect Chrome.Runtime.SendMessage Chrome.Runtime.Connect
Popup-Js - chrome.tabs.sendMessage chrome.tabs.connect - Chrome.Extension.
Hintergrund-Js - chrome.tabs.sendMessage chrome.tabs.connect chrome.extension.getViews -
Devtools-Js Chrome.Devtools - Chrome.Runtime.SendMessage Chrome.Runtime.SendMessage

7.2

Popup und Hintergrund

Das Popup kann die JS -Methode direkt im Hintergrund aufrufen oder direkt auf das DOM des Hintergrunds zugreifen:

// Hintergrund.js
Funktionstest ()
{
	Alarm ('Ich bin Hintergrund!');
}

// popup.js
var bg = chrome.extesion.getbackgroundPage ();
bg.test ();

Eine kleine Episode, die ich heute auf eine Situation gestoßen bin und festgestellt habe, dass das Popup nach langer Zeit keine Methode des Hintergrunds erhalten konnte.

background popup folgt wie folgt (vorausgesetzt, popup ist bereits geöffnet):

var views = chrome.extension.getViews ({type: 'popup'});
if (views.length> 0) {
	console.log (Ansichten [0] .Location.href);
}

Popup oder BG sendet aktiv Nachrichten an Inhalte

Hintergrund.js oder popup.js:

Funktion sendMessAgetocontententscript (Nachricht, Rückruf)
{
	chrome.tabs.query ({active: true, currentWindow: true}, Funktion (Registerkarten)
	{
		Chrome.Tabs.SendMessage (Registerkarten [0] .ID, Nachricht, Funktion (Antwort)
		{
			if (Rückruf) Rückruf (Antwort);
		});
	});
}
sendMessAgetocontentscript ({CMD: 'Test', Wert: 'Hallo, ich bin Popup!'}, Funktion (Antwort)
{
	console.log ('Antwort aus Inhalt:'+Antwort);
});

content-script.js empfängt:

chrome.runtime.onmessage.addListener (Funktion (Anfrage, Absender, SendResponse)
{
	// console.log (sender.tab? "Aus einem Inhaltskript:" + sender.tab.url: "Aus der Erweiterung");
	if (request.cmd == 'test') alarm (request.Value);
	sendResponse ('Ich habe deine Nachricht erhalten!');
});

Was direkt von beiden Parteien in der Kommunikation gesendet wird, sind JSON -Objekte, nicht von JSON -Zeichenfolgen, sodass sie nicht analysieren müssen, was sehr bequem ist (natürlich können Saiten auch direkt gesendet werden).

Einige chrome.runtime.onMessage Codes im Internet verwenden chrome.extension.onMessage .

Das Inhaltskript sendet aktiv Nachrichten an den Hintergrund

content-script.js:

chrome.runtime.sendMessage ({Begrüßung: 'Hallo, ich bin inhalts-skript, ich werde eine Nachricht an das Backend senden!'}, Funktion (Antwort) {
	console.log ('erhielt eine Antwort aus dem Backend:' + Antwort);
});

Hintergrund.js oder popup.js:

// Anhören Sie Nachrichten von Content-script chrome.runtime.onmessage.addListener (Funktion (Anfrage, Absender, SendResponse)
{
	console.log ('Empfangen Sie eine Nachricht von Inhaltskript:');
	console.log (Anfrage, Absender, SendResponse);
	SendResponse ('Ich bin das Backend, ich habe Ihre Nachricht erhalten:' + json.Stringify (Anfrage));
});

Notiz:

  • Die Voraussetzung für Content_Scripts zum aktiven Senden von Nachrichten an popup ist, dass das Popup geöffnet sein muss! Andernfalls müssen Sie den Hintergrund für die Übertragung verwenden.
  • Wenn Hintergrund und Popup gleichzeitig zuhören, können beide die Nachricht gleichzeitig empfangen, aber nur einer kann SendResponse haben.

injiziertes Skript und Inhaltskript

Das einzige, was zwischen content-script und Skripten in der Seite geteilt wird ( injected-script natürlich auch zu Skripten auf der Seite) ist das DOM-Element der Seite.

  • Die Nachrichtenkommunikation zwischen den beiden kann über window.addEventListener window.postMessage erreicht werden.
  • Implementiert durch benutzerdefinierte DOM -Ereignisse;

Die erste Methode (empfohlen):

In injected-script :

window.postMessage ({"test": 'Hallo!'}, '*');

Im Inhaltskript:

window.addeventListener ("meldung", function (e)
{
	console.log (e.data);
}, FALSCH);

Zweite Methode:

In injected-script :

var CustOperEvent = document.createEvent ('Ereignis');
CustoMevent.initevent ('mycustomevent', wahr, wahr);
Funktion firecustomevent (data) {
	hiddendiv = document.getElementById ('mycustomeventDiv');
	Hiddendiv.Innertext = Daten
	Hiddendiv.DispatchEvent (CustOMevent);
}
Firecustomevent ('Hallo, ich bin gewöhnlich JS!');

In content-script.js :

var hiddendiv = document.getElementById ('mycustomeventDiv');
if (! Hiddendiv) {
	hiddendiv = document.createelement ('div');
	hiddendiv.style.display = 'none';
	document.body.appendchild (hiddendiv);
}
hiddendiv.addeventListener ('mycustomevent', function () {
	var eventData = document.getElementById ('mycustomeventDiv'). InnerText;
	console.log ('empfangene benutzerdefinierte Ereignisnachricht:' + eventData);
});

Lange und kurze Verbindungen

Tatsächlich wurde dies oben erwähnt, also werde ich es hier getrennt erklären. Es gibt zwei Kommunikationsmethoden im Chrome-Plug-In, eines ist eine kurze Verbindung ( chrome.tabs.sendMessage und chrome.runtime.sendMessage ), und die andere ist eine lange Verbindung ( chrome.tabs.connect und chrome.runtime.connect ).

Eine kurze Verbindung ist wie eine WebSocket .

Es gibt bereits Codebeispiele für kurze Verbindungen. Hier werden wir nur über lange Verbindungen sprechen.

popup.js:

getCurrentTabid ((tabid) => {
	var port = chrome.tabs.connect (Tabid, {Name: 'Test-Connect'});
	Port.PostMessage ({Frage: 'Wer bist du?'});
	port.onmessage.addListener (Funktion (msg) {
		alert ('empfangene Nachricht:' + msg.answer);
		if (msg.answer && msg.answer.startswith ('i bin'))
		{
			Port.PostMessage ({Frage: 'Oh, du bist es!'});
		}
	});
});

content-script.js:

// Hören Sie für Long Connections chrome.runtime.onconnect.addListener (Funktion (Port) {
	console.log (port);
	if (port.name == 'Test-Connect') {
		port.onmessage.addListener (Funktion (msg) {
			console.log ('empfangene Long -Verbindungsnachricht:', msg);
			if (msg.question == 'Wer bist du?') postMessage ({Antwort: 'Ich bin dein Vater!'});
		});
	}
});

Andere Ergänzungen

Js dynamisch injizieren oder ausführen

Obwohl die Seite DOM nicht direkt im background und popup zugegriffen werden kann, kann auf das DOM der Webseite zugegriffen werden, indem das Skript über chrome.tabs.executeScript ausgeführt wird (beachten Sie, dass diese Methode auch nicht direkt auf die Seite JS zugreifen kann).

Beispiel manifest.json -Konfiguration:

{
	"Name": "Dynamische JS -Injektion Demonstration",
	...
	"Berechtigungen": [
		"tabs", "http: //*/*", "https: //*/*"
	],
	...
}

JS:

// Dynamisch js code chrome.tabs.executescript (tabid, {code: 'document.body.style.backgroundcolor = "red"'}) ausführen;
// Dynamisch JS-Dateien Chrome.tabs.executescript (tabid, {file: 'some-script.js'}) ausführen;

Dynamisch injizieren CSS

Beispiel manifest.json -Konfiguration:

{
	"Name": "Dynamische CSS -Injektion Demo",
	...
	"Berechtigungen": [
		"tabs", "http: //*/*", "https: //*/*"
	],
	...
}

JS-Code:

// Dynamisch CSS -Code ausführen, todo, dies muss verifiziert werden.
// CSS-Dateien dynamisch ausführen.

Holen Sie sich die aktuelle Fenster -ID

Chrome.Windows.getCurrent (Funktion (CurrentWindow)
{
	console.log ('aktuelle Fenster -ID:' + currentWindow.id);
});

Holen Sie sich die aktuelle Registerkarte ID

Es gibt im Allgemeinen 2 Methoden:

// Die aktuelle Registerkarte ID abrufen
Funktion getCurrentTabid (Rückruf)
{
	chrome.tabs.query ({active: true, currentWindow: true}, Funktion (Registerkarten)
	{
		if (Rückruf) Rückruf (tabs.length? tabs [0] .ID: null);
	});
}

Eine andere Möglichkeit, die aktuelle Registerkarten -ID zu erhalten, ist sie meistens ähnlich, nur wenige Male ist sie anders (z. B. wenn das Fenster minimiert wird)

// Die aktuelle Registerkarte ID abrufen
Funktion getCurrentTabid2 ()
{
	Chrome.Windows.getCurrent (Funktion (CurrentWindow)
	{
		chrome.tabs.query ({active: true, windowID: currentWindow.id}, Funktion (Registerkarten)
		{
			if (Rückruf) Rückruf (tabs.length? tabs [0] .ID: null);
		});
	});
}

Lokaler Speicher

Für die lokale Speicherung wird empfohlen, chrome.storage zu localStorage .

  • chrome.storage content-script global background Plugin.
  • chrome.storage.sync kann automatisch mit dem aktuell angemeldeten Benutzer synchronisieren.

chrome.storage.local chrome.storage.sync storage deklarieren.

// Daten lesen.
	console.log (items.color, items.age);
});
// Data chrome.storage.sync.set ({color: 'blau'}, function () {speichern
	console.log ('erfolgreich speichern!');
});

Webrequest

Die WebRequest -Serie von APIs kann verwendet werden, um beforeRequest -Anfragen willkürlich zu ändern.

//Manifest.json
{
	// Berechtigungsantrag "Berechtigungen":
	[
		"WebRequest", // Webanforderung "WebRequestBlocking", // blockieren Webanforderung "Speicher", // Plugin Local Storage "http: //*/*", // Website zugänglich über executescript oder insertCSS "https: //*/*// Website zugänglich über executescript oder insertCSS".
}


// Hintergrund.js
// ob das Bild var ausshowage angezeigt werden soll;
chrome.storage.sync.get ({showimage: true}, function (items) {
	showimage = items.showimage;
});
// Die Überwachung der Webanforderung gibt den letzten Parameter den Blockierungsmodus an, und eine separate Berechtigung muss deklariert werden: WebRequestBlocking
chrome.webrequest.onbeForeRequest.AddListener (Details => {
	// Abbrechen bedeutet, diese Anfrage abbrechen if (! showimage && details.type == 'image') return {abbrechen: true};
	// Einfache Audio- und Videoerkennung // Die meisten Websites verwenden Medien nicht als Videotyp, und das Video ist vor dem Herunterladen geschützt. Dies gilt daher nur zu Demonstrationszwecken und hat keine praktische Bedeutung, wenn (details.type == 'medien') {
		chrome.notifications.create (null, {{
			Typ: 'grundlegend',
			iconurl: 'img/icon.png',
			Titel: 'Audio und Video erkannt',
			Nachricht: 'Audio- und Videoadresse:' + details.Url,
		});
	}
}, {urls: ["<all_urls>"]}, ["Blocking"]);

Internationalisierung

Erstellen Sie einen Ordner mit dem Namen _locales messages.json Plugin -Root -Verzeichnis und erstellen Sie einige default_locale en , zh_TW zh_CN

_locales\en\messages.json Inhalt:

{
	"Plugindesc": {"Nachricht": "Eine einfache Chrome -Erweiterungs -Demo"},
	"HelloWorld": {"Nachricht": "Hallo Welt!"}
}

_locales\zh_CN\messages.json Inhalt:

{
	"Plugindesc": {"Nachricht": "Eine einfache Chrom -Plugin -Demo"},
	"HelloWorld": {"Nachricht": "Hallo, Welt!"}
}

Stellen Sie es in manifest.json und CSS -Dateien ein, über __MSG_messagename__ , wie z. B.:

{
	"Beschreibung": "__msg_plugindesc__",
	// Standardsprache "default_locale": "zh_cn",
}

chrome.i18n.getMessage("helloWorld") .

Schalten Sie beim Testen die Sprache, indem Sie eine andere Verknüpfung für Chrome erstellen chrome.exe --lang=en , z. B.:

Englischer Effekt:

Chinesischer Effekt:

API -Zusammenfassung

Einige häufig verwendete API -Serien:

  • Chrome.tabs
  • Chrome.Runtime
  • Chrome.WebRequest
  • Chrome.Window
  • Chrome.Storage
  • Chrome.ContextMenus
  • chrome.devtools
  • chrome.extesion

Gelernte Lektionen

Zeigen Sie den installierten Plugin -Pfad an

Der Quellcode-Pfad der installierten Plug-Ins lautet: C:\Users\用戶名\AppData\Local\Google\Chrome\User Data\Default\Extensions .

Wie kann man die ID eines Plugins betrachten? Gehen Sie zu Chrome: // Erweiterungen und überprüfen Sie das Kontrollkästchen für den Entwicklermodus.

Achten Sie besonders auf Hintergrundfehler

Oft stellen Sie fest, dass Ihr Code unerklärlich ausfällt und den Grund nicht finden kann, wie sehr Sie sich bemühen.

So verhindern Sie, dass die Popup -Seite schließt

Bei der Überprüfung von Elementen auf einer Popup -Seite wird das Popup gezwungen und kann nicht geschlossen werden. Dieser Ansatz ist in einigen Fällen nützlich!

Unterstützt die Inline -JavaScript -Ausführung nicht

Das heißt, es unterstützt nicht das Schreiben von JS direkt in HTML, zum Beispiel:

<input id = "btn" type = "button" value = "sammeln" onclick = "test ()"/>

Der Fehler lautet wie folgt:

Weigerte sich, Inline-Ereignis-Handler auszuführen, da er gegen die folgende Richtlinie der Inhaltssicherheit verstößt: "Skript-Src 'Self' Blob: Dateisystem: Chrome-Extension-Ressourcen:".

Die Lösung besteht darin, JS zu verwenden, um Ereignisse zu binden:

$ ('#btn'). on ('click', function () {alert ('test')});

Darüber hinaus schreiben Sie für das A-Tag href="javascript:;" rel="external nofollow" rel="external nofollow" href="#" rel="external nofollow"

Wenn Sie schreiben:

<a href = "JavaScript:;"

Der Fehler lautet wie folgt:

Weigerte sich, JavaScript-URL auszuführen, weil sie die folgende Richtlinie der Inhaltssicherheit verletzt: "Skript-Src 'Self' Blob: Dateisystem: Chrome-Extension-Ressource:" entweder das "unsichere Inline" -Keyword, ein Hash ('sha256 -...') oder a nonce ('Nonce-..').

Seien Sie vorsichtig, wenn Sie CSS injizieren

Da die durch content_scripts injizierten CSS eine sehr hohe Priorität haben, fast die zweite für den Browser -Standardstil, kann dies den Anzeigeeffekt einiger Websites beeinflussen, wenn Sie nicht vorsichtig sind. Versuchen Sie also, keine Stile zu schreiben, die sich auf die globale Situation auswirken.

Der Grund, warum ich dies betone, ist, dass die Probleme, die es mit sich bringt, sehr versteckt und nicht leicht zu finden sind. Dann haben Sie lange hart gesucht und herausgefunden, dass es tatsächlich von einem Stil im Plug-In betroffen war!

Verpackung und Veröffentlichung

Wenn Sie sich packen möchten, befindet sich auf der Plugin -Verwaltungsseite direkt eine Paketschaltfläche:

Dann wird eine .crx -Datei generiert.

siehe

Offizielle Informationen

Es wird empfohlen, die offiziellen Dokumente zu überprüfen.

Chrome Plugin Offizielle Dokumentation Homepage

Offizielles Beispiel für Chrom -Plugin

Manifestdatei

Berechtigungen

Detaillierte Erläuterung der Syntax von Fuzzy -Matching -Regeln im Dokument von Chrome.xxx.api

Informationen von Drittanbietern

Einige chinesische Materialien, nicht besonders empfohlen:

360 Dokumentation für sichere Browserentwicklung

360 -Speed ​​-Browser

Chrome -Erweiterungsentwicklungsdokumentation

Chrome Extension Development Geek Series Blog

Beigefügte Fotos

Angehängliches Bild: Chrom Hochdefinition PNG Format Logo:

Das obige ist der detaillierte Inhalt des Complete Guide to Chrome Plug-in (Erweiterung).

Das könnte Sie auch interessieren:
  • 10 Langkalierende Chrom-Browser-Plug-Ins (Muss für Programmierer)
  • Chrome Developer Assistant Plugin V2.10 Veröffentlicht Verbesserung der Entwicklungseffizienz ist nicht mehr nur ein Slogan
  • So verwenden Sie Chrome Dev Tools, um die Seitenleistung zu analysieren (Front-End-Leistungsoptimierung)
  • Lösen Sie das Problem von Selenium+Headless Chrom, um automatisch ohne Pop-up
  • Lösung für das Problem, den Prozess des Chromedrivers/Geckodrivers nach Selen nicht zu schließen (Java Version + Python -Version)
  • Verwenden von Postman- und Chrome -Entwicklerfunktion Exploration Project (Abschlussprojekt)
  • Vue entwickelt ein Chrome-Plug-In, um Schnittstellendaten zu erhalten und in der Datenbank zu speichern
  • Beispiel für das Parsen von Chrom -Browser -Lesezeichen mit Python
  • So erstellen Sie eine Chrome -Erweiterung für jemand anderen

<<:  Kopieren Sie den Inhalt einer Datei an das Ende einer anderen Datei in Linux

>>:  Detaillierte Schritte zur Installation von MySQL auf CentOS 7

Artikel empfehlen

Lösen Sie das Problem des Docker-Pull-Image-Fehlers

beschreiben: Installieren Sie die VM unter Window...

Drei Strategien zum Umschreiben von MySQL-Abfrageanweisungen

Inhaltsverzeichnis Komplexe Abfrage und schrittwe...

Wie erreicht MySQL eine Master-Slave-Synchronisierung?

Die Master-Slave-Synchronisierung, auch Master-Sl...

Natives JS zum Erreichen von Spezialeffekt-Meldungsfeldern

In diesem Artikel wird ein Nachrichtenfeld mit Sp...

Detaillierte Schritte zum Einrichten eines Nexus-Servers

1. Die Bedeutung des Aufbaus eines Nexus-Dienstes...

Lösung für MySQL-Fehlercode 1862 Ihr Passwort ist abgelaufen

Der Blogger hat MySQL ein oder zwei Monate lang n...

Detaillierte Erklärung des FreeList-Mechanismus von MySQL

1. Einleitung Nach dem Start von MySQL wird Buffe...

Proxy realisiert das Prinzip der bidirektionalen Bindung von Vue3-Daten

Inhaltsverzeichnis 1. Vorteile von Proxy gegenübe...

Vue-Anfängerhandbuch: Erstellen des ersten Vue-cli-Scaffolding-Programms

1. Vue – Das erste Vue-CLI-Programm Die Entwicklu...

Detaillierte Erläuterung der MySQL-Transaktionsverwaltungsvorgänge

Dieser Artikel beschreibt die MySQL-Transaktionsv...

Was Sie über MySQL-Sperren wissen müssen

1. Einleitung MySQL-Sperren können je nach Umfang...