runtime.onMessage
Verwenden Sie dieses Ereignis, um Nachrichten von einem anderen Teil Ihrer Erweiterung zu empfangen.
Einige Anwendungsbeispiele sind:
- in einem Content-Skript, um Nachrichten von einem Hintergrundskript zu empfangen.
- in einem Hintergrundskript, um Nachrichten von einem Content-Skript zu empfangen.
- in einer Optionsseite oder einem Popup-Skript, um Nachrichten von einem Hintergrundskript zu empfangen.
- in einem Hintergrundskript, um Nachrichten von einer Optionsseite oder einem Popup-Skript zu empfangen.
Um eine Nachricht zu senden, die vom onMessage()
-Listener empfangen wird, verwenden Sie runtime.sendMessage()
oder (um eine Nachricht an ein Content-Skript zu senden) tabs.sendMessage()
.
Hinweis: Vermeiden Sie es, mehrere onMessage()
-Listener für denselben Nachrichtentyp zu erstellen, da die Reihenfolge, in der die Listener ausgelöst werden, nicht garantiert ist.
Wenn Sie die Zustellung einer Nachricht an einen bestimmten Endpunkt garantieren möchten, verwenden Sie den verbindungsbasierten Ansatz, um Nachrichten auszutauschen.
Zusammen mit der Nachricht selbst erhält der Listener folgende Informationen:
- ein
sender
Objekt, das Details über den Absender der Nachricht enthält. - eine
sendResponse()
Funktion, die verwendet werden kann, um eine Antwort an den Absender zu senden.
Sie können eine synchronisierte Antwort auf die Nachricht senden, indem Sie die sendResponse()
Funktion innerhalb Ihres Listeners aufrufen. Siehe ein Beispiel.
Um eine asynchrone Antwort zu senden, gibt es zwei Optionen:
- Geben Sie
true
vom Ereignislistener zurück. Dadurch bleibt diesendResponse()
Funktion nach der Rückkehr des Listeners gültig, sodass Sie sie später aufrufen können. Siehe ein Beispiel.Warnung: Präfixen Sie die Funktion nicht mit
async
. Das Präfixieren mitasync
ändert die Bedeutung zu Senden einer asynchronen Antwort mit einem Promise, was im Wesentlichen dasselbe ist wiesendResponse(true)
. - Geben Sie ein
Promise
vom Ereignislistener zurück, und lösen Sie es auf, wenn Sie die Antwort haben (oder lehnen Sie es im Falle eines Fehlers ab). Siehe ein Beispiel.
Hinweis: Sie können auch einen verbindungsbasierten Ansatz verwenden, um Nachrichten auszutauschen.
Syntax
browser.runtime.onMessage.addListener(listener)
browser.runtime.onMessage.removeListener(listener)
browser.runtime.onMessage.hasListener(listener)
Ereignisse haben drei Funktionen:
addListener(listener)
-
Fügt diesem Ereignis einen Listener hinzu.
removeListener(listener)
-
Hört auf, dieses Ereignis zu überwachen. Das
listener
-Argument ist der zu entfernende Listener. hasListener(listener)
-
Überprüft, ob mindestens ein Listener für dieses Ereignis registriert ist. Gibt
true
zurück, wenn es überwacht wird, andernfallsfalse
.
addListener-Syntax
Parameter
listener
-
Die Funktion, die aufgerufen wird, wenn dieses Ereignis auftritt. Die Funktion erhält folgende Argumente:
message
-
object
. Die Nachricht selbst. Dies ist ein serialisierbares Objekt (siehe Datenklon-Algorithmus). sender
-
Ein
runtime.MessageSender
Objekt, das den Absender der Nachricht repräsentiert. sendResponse
-
Eine Funktion, die höchstens einmal aufgerufen wird, um eine Antwort auf die
message
zu senden. Die Funktion nimmt ein einziges Argument an, das jedes serialisierbare Objekt sein kann (siehe Datenklon-Algorithmus). Dieses Argument wird an den Nachrichtenabsender zurückgegeben.Wenn Sie mehr als einen
onMessage()
-Listener im selben Dokument haben, darf nur einer eine Antwort senden.Um eine Antwort synchron zu senden, rufen Sie
sendResponse()
auf, bevor die Listener-Funktion zurückkehrt.Um eine Antwort asynchron zu senden:
-
behalten Sie entweder eine Referenz auf das
sendResponse()
-Argument und geben Sietrue
von der Listener-Funktion zurück. Sie können dannsendResponse()
aufrufen, nachdem die Listener-Funktion zurückgekehrt ist. -
oder geben Sie ein
Promise
von der Listener-Funktion zurück und lösen Sie das Promise auf, wenn die Antwort bereit ist. Dies ist die bevorzugte Methode.Hinweis: Promise als Rückgabewert wird in Chrome nicht unterstützt, bis Chrome bug 1185241 gelöst ist. Als Alternative return true und verwenden Sie sendResponse.
-
Die
listener
-Funktion kann entweder einen Boolean oder einPromise
zurückgeben.Hinweis: Wenn Sie eine asynchrone Funktion an
addListener()
übergeben, gibt der Listener ein Promise für jede empfangene Nachricht zurück, was verhindert, dass andere Listener antworten:js// nicht so machen browser.runtime.onMessage.addListener(async (data, sender) => { if (data.type === "handle_me") { return "done"; } });
Wenn Sie möchten, dass der Listener nur auf Nachrichten eines bestimmten Typs reagiert, müssen Sie den Listener als nicht-
async
Funktion definieren und nur für die Nachrichten ein Promise zurückgeben, auf die der Listener reagieren soll – und ansonsten false oder undefined zurückgeben:jsbrowser.runtime.onMessage.addListener((data, sender) => { if (data.type === "handle_me") { return Promise.resolve("done"); } return false; });
Browser-Kompatibilität
BCD tables only load in the browser
Beispiele
Einfaches Beispiel
Dieses Content-Skript hört auf Klick-Ereignisse auf der Webseite. Wenn der Klick auf einen Link erfolgte, sendet es eine Nachricht an die Hintergrundseite mit der Ziel-URL:
// content-script.js
window.addEventListener("click", notifyExtension);
function notifyExtension(e) {
if (e.target.tagName !== "A") {
return;
}
browser.runtime.sendMessage({ url: e.target.href });
}
Das Hintergrundskript hört auf diese Nachrichten und zeigt eine Benachrichtigung mit der notifications
API an:
// background-script.js
browser.runtime.onMessage.addListener(notify);
function notify(message) {
browser.notifications.create({
type: "basic",
iconUrl: browser.extension.getURL("link.png"),
title: "You clicked a link!",
message: message.url,
});
}
Senden einer synchronen Antwort
Dieses Content-Skript sendet eine Nachricht an das Hintergrundskript, wenn der Benutzer auf die Seite klickt. Es protokolliert auch alle Antworten, die vom Hintergrundskript gesendet werden:
// content-script.js
function handleResponse(message) {
console.log(`background script sent a response: ${message.response}`);
}
function handleError(error) {
console.log(`Error: ${error}`);
}
function sendMessage(e) {
const sending = browser.runtime.sendMessage({
content: "message from the content script",
});
sending.then(handleResponse, handleError);
}
window.addEventListener("click", sendMessage);
Hier ist eine Version des entsprechenden Hintergrundskripts, die eine Antwort synchron, von innen im Listener, sendet:
// background-script.js
function handleMessage(request, sender, sendResponse) {
console.log(`content script sent a message: ${request.content}`);
sendResponse({ response: "response from background script" });
}
browser.runtime.onMessage.addListener(handleMessage);
Und hier ist eine weitere Version, die Promise.resolve()
verwendet:
// background-script.js
function handleMessage(request, sender, sendResponse) {
console.log(`content script sent a message: ${request.content}`);
return Promise.resolve({ response: "response from background script" });
}
browser.runtime.onMessage.addListener(handleMessage);
Senden einer asynchronen Antwort unter Verwendung von sendResponse
Hier ist eine alternative Version des Hintergrundskripts aus dem vorherigen Beispiel. Es sendet eine Antwort asynchron, nachdem der Listener zurückgekehrt ist. Beachten Sie return true;
im Listener: Dies teilt dem Browser mit, dass Sie beabsichtigen, das sendResponse
-Argument nach der Rückkehr des Listeners zu verwenden.
// background-script.js
function handleMessage(request, sender, sendResponse) {
console.log(`content script sent a message: ${request.content}`);
setTimeout(() => {
sendResponse({ response: "async response from background script" });
}, 1000);
return true;
}
browser.runtime.onMessage.addListener(handleMessage);
Warnung: Präfixen Sie die Funktion nicht mit async
. Das Präfixieren mit async
ändert die Bedeutung zu Senden einer asynchronen Antwort mit einem Promise, was im Wesentlichen dasselbe ist wie sendResponse(true)
.
Senden einer asynchronen Antwort mit einem Promise
Hinweis: Promise als Rückgabewert wird in Chrome nicht unterstützt, bis Chrome bug 1185241 gelöst ist. Als Alternative return true und verwenden Sie sendResponse
.
Dieses Content-Skript erhält den ersten <a>
-Link auf der Seite und sendet eine Nachricht, um zu fragen, ob der Speicherort des Links ein Lesezeichen ist. Es erwartet eine Boolean-Antwort (true
, wenn der Speicherort ein Lesezeichen ist, andernfalls false
):
// content-script.js
const firstLink = document.querySelector("a");
function handleResponse(isBookmarked) {
if (isBookmarked) {
firstLink.classList.add("bookmarked");
}
}
browser.runtime
.sendMessage({
url: firstLink.href,
})
.then(handleResponse);
Hier ist das Hintergrundskript. Es verwendet
um zu überprüfen, ob der Link ein Lesezeichen ist, was ein bookmarks.search()
Promise
zurückgibt:
// background-script.js
function isBookmarked(message, sender, response) {
return browser.bookmarks
.search({
url: message.url,
})
.then((results) => results.length > 0);
}
browser.runtime.onMessage.addListener(isBookmarked);
Wenn der asynchrone Handler kein Promise zurückgibt, können Sie ein Promise explizit konstruieren. Dieses eher konstruierte Beispiel sendet eine Antwort nach einer 1-Sekunden-Verzögerung, unter Verwendung von setTimeout()
:
// background-script.js
function handleMessage(request, sender, sendResponse) {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ response: "async response from background script" });
}, 1000);
});
}
browser.runtime.onMessage.addListener(handleMessage);
Beispiel-Erweiterungen
- beastify
- content-script-register
- cookie-bg-picker
- devtools-panels
- export-helpers
- find-across-tabs
- imagify
- mocha-client-tests
- notify-link-clicks-i18n
- store-collected-images
- user-script-register
- webpack-modules
Hinweis: Diese API basiert auf der chrome.runtime
API von Chromium. Diese Dokumentation ist abgeleitet von runtime.json
im Chromium-Code.