Übersicht
Eine DevTools-Erweiterung fügt den Chrome-Entwicklertools Funktionen hinzu. Sie können neue UI-Bereiche und Seitenleisten hinzufügen, mit der untersuchten Seite interagieren und Informationen zu Netzwerkanfragen abrufen. Empfohlene Entwicklertools-Erweiterungen ansehen DevTools-Erweiterungen haben Zugriff auf eine zusätzliche Reihe von DevTools-spezifischen Erweiterungs-APIs:
Eine Entwicklertools-Erweiterung ist wie jede andere Erweiterung aufgebaut: Sie kann eine Hintergrundseite, Content-Scripts und andere Elemente haben. Außerdem hat jede DevTools-Erweiterung eine DevTools-Seite, die Zugriff auf die DevTools-APIs hat.

Die Seite „Entwicklertools“
Jedes Mal, wenn ein Entwicklertools-Fenster geöffnet wird, wird eine Instanz der Entwicklertools-Seite der Erweiterung erstellt. Die Seite „Entwicklertools“ ist so lange vorhanden wie das Fenster mit den Entwicklertools. Die Entwicklertools-Seite hat Zugriff auf die Entwicklertools-APIs und eine begrenzte Anzahl von Erweiterungs-APIs. Die Seite „Entwicklertools“ kann:
- Mithilfe der
devtools.panels-APIs können Sie Panels erstellen und mit ihnen interagieren. - Informationen zum untersuchten Fenster abrufen und Code im untersuchten Fenster mit den
devtools.inspectedWindow-APIs auswerten. - Mit den
devtools.network-APIs können Sie Informationen zu Netzwerkanfragen abrufen.
Die Entwicklertools-Seite kann die meisten Erweiterungs-APIs nicht direkt verwenden. Es hat Zugriff auf dieselbe Teilmenge der APIs extension und runtime wie ein Content-Script. Wie ein Content-Script kann eine Entwicklertools-Seite über Message Passing mit der Hintergrundseite kommunizieren. Ein Beispiel finden Sie unter Content-Script einfügen.
Entwicklertools-Erweiterung erstellen
Wenn Sie eine Entwicklertools-Seite für Ihre Erweiterung erstellen möchten, fügen Sie das Feld devtools_page in das Erweiterungsmanifest ein:
{
"name": ...
"version": "1.0",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
Für jedes geöffnete Entwicklertools-Fenster wird eine Instanz von devtools_page erstellt, die im Manifest Ihrer Erweiterung angegeben ist. Auf der Seite können mithilfe der devtools.panels-API weitere Erweiterungsseiten als Bereiche und Seitenleisten zum Entwicklertools-Fenster hinzugefügt werden.
Die chrome.devtools.*-API-Module sind nur für die Seiten verfügbar, die im DevTools-Fenster geladen werden. Content-Scripts und andere Erweiterungsseiten haben keinen Zugriff auf diese APIs. Die APIs sind also nur während der Lebensdauer des DevTools-Fensters verfügbar.
Einige DevTools-APIs sind noch experimentell. Weitere Informationen finden Sie unter chrome.experimental.* APIs finden Sie eine Liste der experimentellen APIs und Richtlinien zu ihrer Verwendung.
UI-Elemente der Entwicklertools: Bereiche und Seitenleistenbereiche
Zusätzlich zu den üblichen UI-Elementen für Erweiterungen wie Browseraktionen, Kontextmenüs und Pop-ups kann eine Entwicklertools-Erweiterung UI-Elemente zum Entwicklertools-Fenster hinzufügen:
- Ein Bereich ist ein Tab der obersten Ebene, z. B. die Bereiche „Elemente“, „Quellen“ und „Netzwerk“.
- In einem Seitenleistenbereich wird eine zusätzliche Benutzeroberfläche für einen Bereich angezeigt. Die Bereiche „Stile“, „Berechnete Stile“ und „Event-Listener“ im Bereich „Elemente“ sind Beispiele für Seitenleistenbereiche. Hinweis: Das Aussehen der Seitenleistenbereiche kann je nach verwendeter Chrome-Version und Andockposition des Entwicklertools-Fensters vom Bild abweichen.

Jedes Feld ist eine eigene HTML-Datei, die andere Ressourcen (JavaScript, CSS, Bilder usw.) enthalten kann. So erstellen Sie ein einfaches Feld:
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
JavaScript, das in einem Bereich oder Seitenleistenbereich ausgeführt wird, hat Zugriff auf dieselben APIs wie die DevTools-Seite.
So erstellen Sie einen einfachen Seitenleistenbereich für den Bereich „Elemente“:
chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function(sidebar) {
// sidebar initialization code here
sidebar.setObject({ some_data: "Some data to show" });
});
Es gibt mehrere Möglichkeiten, Inhalte in einem Seitenleistenbereich anzuzeigen:
- HTML-Inhalt. Rufen Sie
setPageauf, um eine HTML-Seite anzugeben, die im Bereich angezeigt werden soll. - JSON-Daten. Übergeben Sie ein JSON-Objekt an
setObject. - JavaScript-Ausdruck. Übergeben Sie einen Ausdruck an
setExpression. DevTools wertet den Ausdruck im Kontext der untersuchten Seite aus und zeigt den Rückgabewert an.
Für setObject und setExpression wird im Bereich der Wert angezeigt, wie er in der Entwicklertools-Konsole zu sehen wäre. Mit setExpression können Sie jedoch DOM-Elemente und beliebige JavaScript-Objekte anzeigen, während setObject nur JSON-Objekte unterstützt.
Kommunikation zwischen Erweiterungskomponenten
In den folgenden Abschnitten werden einige typische Szenarien für die Kommunikation zwischen den verschiedenen Komponenten einer Entwicklertools-Erweiterung beschrieben.
Inhaltskript einfügen
Die Entwicklertools-Seite kann tabs.executeScript nicht direkt aufrufen. Wenn Sie ein Content-Script über die Entwicklertools-Seite einfügen möchten, müssen Sie die ID des Tabs des untersuchten Fensters mit dem Attribut inspectedWindow.tabId abrufen und eine Nachricht an die Hintergrundseite senden. Rufen Sie auf der Hintergrundseite tabs.executeScript auf, um das Skript einzufügen.
Die folgenden Code-Snippets zeigen, wie ein Content-Script mit executeScript eingefügt wird.
// DevTools page -- devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
backgroundPageConnection.onMessage.addListener(function (message) {
// Handle responses from the background page, if any
});
// Relay the tab ID to the background page
chrome.runtime.sendMessage({
tabId: chrome.devtools.inspectedWindow.tabId,
scriptToInject: "content_script.js"
});
Code für die Hintergrundseite:
// Background page -- background.js
chrome.runtime.onConnect.addListener(function(devToolsConnection) {
// assign the listener function to a variable so we can remove it later
var devToolsListener = function(message, sender, sendResponse) {
// Inject a content script into the identified tab
chrome.tabs.executeScript(message.tabId,
{ file: message.scriptToInject });
}
// add the listener
devToolsConnection.onMessage.addListener(devToolsListener);
devToolsConnection.onDisconnect.addListener(function() {
devToolsConnection.onMessage.removeListener(devToolsListener);
});
});
JavaScript im untersuchten Fenster auswerten
Mit der Methode inspectedWindow.eval können Sie JavaScript-Code im Kontext der untersuchten Seite ausführen. Sie können die Methode eval über eine DevTools-Seite, ein DevTools-Fenster oder einen Seitenleistenbereich aufrufen.
Standardmäßig wird der Ausdruck im Kontext des Hauptframes der Seite ausgewertet. Vielleicht kennen Sie bereits die Befehlszeilen-API der Entwicklertools, mit der Sie Elemente untersuchen (inspect(elem)), Haltepunkte für Funktionen festlegen (debug(fn)) oder Inhalte in die Zwischenablage kopieren (copy()) können.
inspectedWindow.eval() verwendet denselben Skriptausführungskontext und dieselben Optionen wie der in den Entwicklertools eingegebene Code. Dadurch ist der Zugriff auf diese APIs innerhalb von „eval“ möglich. SOAK verwendet es beispielsweise, um ein Element zu untersuchen:
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script[data-soak=main]')[0])",
function(result, isException) { }
);
Alternativ können Sie die Option useContentScriptContext: true für inspectedWindow.eval() verwenden, um den Ausdruck im selben Kontext wie die Inhaltsskripts auszuwerten. Durch den Aufruf von eval mit useContentScriptContext: true wird kein Content-Script-Kontext erstellt. Sie müssen also ein Kontext-Script laden, bevor Sie eval aufrufen. Das kann entweder durch den Aufruf von executeScript oder durch die Angabe eines Content-Scripts in der Datei manifest.json erfolgen.
Sobald der Kontext des Kontextskripts vorhanden ist, können Sie mit dieser Option zusätzliche Inhaltsskripts einschleusen.
Die Methode eval ist leistungsstark, wenn sie im richtigen Kontext verwendet wird, und gefährlich, wenn sie unangemessen eingesetzt wird. Verwenden Sie die Methode tabs.executeScript, wenn Sie keinen Zugriff auf den JavaScript-Kontext der untersuchten Seite benötigen. Ausführliche Warnungen und einen Vergleich der beiden Methoden finden Sie unter inspectedWindow.
Ausgewähltes Element an ein Inhaltsscript übergeben
Das Content-Script hat keinen direkten Zugriff auf das aktuell ausgewählte Element. Code, den Sie mit inspectedWindow.eval ausführen, hat jedoch Zugriff auf die Entwicklertools-Konsole und die Befehlszeilen-APIs.
Im ausgewerteten Code können Sie beispielsweise mit $0 auf das ausgewählte Element zugreifen.
So übergeben Sie das ausgewählte Element an ein Inhaltsskript:
- Erstellen Sie eine Methode im Content-Script, die das ausgewählte Element als Argument verwendet.
- Rufen Sie die Methode über die Entwicklertools-Seite mit
inspectedWindow.evalund der OptionuseContentScriptContext: trueauf.
Der Code in Ihrem Content-Script könnte so aussehen:
function setSelectedElement(el) {
// do something with the selected element
}
Rufen Sie die Methode so über die Seite „Entwicklertools“ auf:
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
{ useContentScriptContext: true });
Die Option useContentScriptContext: true gibt an, dass der Ausdruck im selben Kontext wie die Inhaltsskripts ausgewertet werden muss, damit auf die Methode setSelectedElement zugegriffen werden kann.
window eines Referenzbereichs abrufen
Um postMessage über ein DevTools-Panel auszuführen, benötigen Sie einen Verweis auf das zugehörige window-Objekt.
So rufen Sie das Iframe-Fenster eines Bereichs über den panel.onShown-Event-Handler ab:
onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
Nachrichten von Inhaltsskripten an die Entwicklertools-Seite
Die Kommunikation zwischen der DevTools-Seite und Inhaltsskripts erfolgt indirekt über die Hintergrundseite.
Wenn eine Nachricht an ein Content-Script gesendet wird, kann die Hintergrundseite die Methode tabs.sendMessage verwenden, mit der eine Nachricht an die Content-Scripts auf einem bestimmten Tab gesendet wird, wie unter Content-Script einfügen beschrieben.
Wenn Sie eine Nachricht aus einem Content-Script senden, gibt es keine vorgefertigte Methode, um eine Nachricht an die richtige DevTools-Seiteninstanz zu senden, die dem aktuellen Tab zugeordnet ist. Als Workaround können Sie die Entwicklertools-Seite eine langlebige Verbindung zur Hintergrundseite herstellen lassen und die Hintergrundseite eine Zuordnung von Tab-IDs zu Verbindungen verwalten lassen, damit jede Nachricht an die richtige Verbindung weitergeleitet werden kann.
// background.js
var connections = {};
chrome.runtime.onConnect.addListener(function (port) {
var extensionListener = function (message, sender, sendResponse) {
// The original connection event doesn't include the tab ID of the
// DevTools page, so we need to send it explicitly.
if (message.name == "init") {
connections[message.tabId] = port;
return;
}
// other message handling
}
// Listen to messages sent from the DevTools page
port.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
port.onMessage.removeListener(extensionListener);
var tabs = Object.keys(connections);
for (var i=0, len=tabs.length; i < len; i++) {
if (connections[tabs[i]] == port) {
delete connections[tabs[i]]
break;
}
}
});
});
// Receive message from content script and relay to the devTools page for the
// current tab
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// Messages from content scripts should have sender.tab set
if (sender.tab) {
var tabId = sender.tab.id;
if (tabId in connections) {
connections[tabId].postMessage(request);
} else {
console.log("Tab not found in connection list.");
}
} else {
console.log("sender.tab not defined.");
}
return true;
});
Die Entwicklertools-Seite (oder der Bereich oder Seitenleistenbereich) stellt die Verbindung so her:
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "panel"
});
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
});
Nachrichten von eingefügten Skripts an die Entwicklertools-Seite
Die oben beschriebene Lösung funktioniert zwar für Content-Scripts, für Code, der direkt in die Seite eingefügt wird (z.B. durch Anhängen eines <script>-Tags oder durch inspectedWindow.eval), ist jedoch eine andere Strategie erforderlich. In diesem Kontext leitet runtime.sendMessage Nachrichten nicht wie erwartet an das Hintergrundskript weiter.
Als Workaround können Sie Ihr eingefügtes Skript mit einem Inhaltsskript kombinieren, das als Vermittler fungiert. Wenn Sie Nachrichten an das Content-Script übergeben möchten, können Sie die window.postMessage-API verwenden. Hier ist ein Beispiel, das auf dem Hintergrundskript aus dem vorherigen Abschnitt basiert:
// injected-script.js
window.postMessage({
greeting: 'hello there!',
source: 'my-devtools-extension'
}, '*');
// content-script.js
window.addEventListener('message', function(event) {
// Only accept messages from the same frame
if (event.source !== window) {
return;
}
var message = event.data;
// Only accept messages that we know are ours
if (typeof message !== 'object' || message === null ||
!message.source === 'my-devtools-extension') {
return;
}
chrome.runtime.sendMessage(message);
});
Ihre Nachricht wird jetzt vom eingefügten Skript über das Inhaltsskript und das Hintergrundskript an die Entwicklertools-Seite weitergeleitet.
Hier finden Sie zwei alternative Techniken für die Nachrichtenübergabe.
Erkennen, wenn die Entwicklertools geöffnet und geschlossen werden
Wenn Ihre Erweiterung erfassen muss, ob das Entwicklertools-Fenster geöffnet ist, können Sie der Hintergrundseite einen onConnect-Listener hinzufügen und connect über die Entwicklertools-Seite aufrufen. Da für jeden Tab ein eigenes Entwicklertools-Fenster geöffnet sein kann, erhalten Sie möglicherweise mehrere Verbindungsereignisse. Um zu erfassen, ob ein Entwicklertools-Fenster geöffnet ist, müssen Sie die Verbindungs- und Trennungsereignisse wie unten dargestellt zählen:
// background.js
var openCount = 0;
chrome.runtime.onConnect.addListener(function (port) {
if (port.name == "devtools-page") {
if (openCount == 0) {
alert("DevTools window opening.");
}
openCount++;
port.onDisconnect.addListener(function(port) {
openCount--;
if (openCount == 0) {
alert("Last DevTools window closing.");
}
});
}
});
Auf der Seite „Entwicklertools“ wird eine Verbindung so hergestellt:
// devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
Beispiele für Entwicklertools-Erweiterungen
Hier finden Sie den Quellcode dieser Beispiele für DevTools-Erweiterungen:
- Polymer Devtools Extension: Hier werden viele Helfer auf der Hostseite ausgeführt, um den DOM-/JS-Status abzufragen und an das benutzerdefinierte Feld zurückzusenden.
- React DevTools-Erweiterung: Hier wird ein Untermodul von Blink verwendet, um UI-Komponenten der Entwicklertools wiederzuverwenden.
- Ember Inspector: Gemeinsamer Erweiterungskern mit Adaptern für Chrome und Firefox.
- Coquette-inspect: Eine saubere React-basierte Erweiterung mit einem Debugging-Agent, der in die Hostseite eingefügt wird.
- In unserer Entwicklertools-Erweiterungsgalerie und in den Beispielerweiterungen finden Sie weitere nützliche Apps, die Sie installieren, ausprobieren und von denen Sie lernen können.
Weitere Informationen
Informationen zu den Standard-APIs, die von Erweiterungen verwendet werden können, finden Sie unter chrome.*. APIs und Web-APIs.
Geben Sie uns Feedback. Ihre Kommentare und Vorschläge helfen uns, die APIs zu verbessern.
Beispiele
Beispiele für die Verwendung von Entwicklertools-APIs finden Sie unter Samples.