runtime.onMessage
Verwenden Sie dieses Ereignis, um Nachrichten aus einem anderen Teil Ihrer Erweiterung zu empfangen.
Einige Anwendungsbeispiele sind:
- in einem Content Script, um Nachrichten von einem Background Script zu empfangen.
- in einem Background Script, um Nachrichten von einem Content Script zu empfangen.
- in einem Skript einer Optionsseite oder eines Popups, um Nachrichten von einem Background Script zu empfangen.
- in einem Background Script, um Nachrichten von einer Optionsseite oder einem Popup-Skript zu empfangen.
- in einem Skript auf einer Erweiterungsseite, um Nachrichten zu empfangen, die die Ausführung von Code in den Skripten der Seite anfordern.
Um eine Nachricht zu senden, die vom onMessage()-Listener empfangen wird, verwenden Sie runtime.sendMessage() oder (um eine Nachricht an ein Content Script zu senden) tabs.sendMessage().
Hinweis:
Vermeiden Sie es, mehrere onMessage()-Listener für denselben Nachrichtentyp zu erstellen, da die Reihenfolge, in der mehrere Listener ausgeführt werden, nicht garantiert ist.
Wenn Sie die Zustellung einer Nachricht an einen bestimmten Endpunkt garantieren möchten, verwenden Sie den verbindungsbasierten Ansatz zum Nachrichtenaustausch.
Zusammen mit der Nachricht selbst wird dem Listener übergeben:
- ein
sender-Objekt mit Details über den Absender der Nachricht. - eine
sendResponse()-Funktion, die verwendet werden kann, um dem Absender eine Antwort zu senden.
Sie können eine synchrone Antwort auf die Nachricht senden, indem Sie innerhalb Ihres Listeners die sendResponse()-Funktion aufrufen. Siehe das Beispiel für das Senden einer synchronen Antwort.
Um eine asynchrone Antwort zu senden, gibt es zwei Optionen:
- Geben Sie
truevom Ereignis-Listener zurück. Dadurch bleibt diesendResponse()-Funktion gültig, nachdem der Listener zurückkehrt, sodass Sie sie später aufrufen können. Siehe das Beispiel für das Senden einer asynchronen Antwort mitsendResponse.Warnung: Fügen Sie der Funktion nicht
asyncvoran.asyncvoranzufügen, ändert die Bedeutung in Senden einer asynchronen Antwort mit einem Promise, was im Wesentlichen dasselbe ist wiesendResponse(true). - Geben Sie ein
Promisevom Ereignis-Listener zurück und lösen Sie es, wenn Sie die Antwort haben (oder lehnen Sie es im Falle eines Fehlers ab). Siehe das Beispiel für das Senden einer asynchronen Antwort mit einem Promise.
Hinweis: Sie können auch einen verbindungsbasierten Ansatz zum Nachrichtenaustausch verwenden.
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)-
Beendet das Lauschen auf dieses Ereignis. Das
listener-Argument ist der zu entfernende Listener. hasListener(listener)-
Überprüft, ob mindestens ein Listener für dieses Ereignis registriert ist. Gibt
truezurück, wenn gelauscht wird, andernfallsfalse.
addListener-Syntax
>Parameter
listener-
Die Funktion, die aufgerufen wird, wenn dieses Ereignis eintritt. Die Funktion erhält die folgenden Argumente:
message-
object. Die Nachricht. 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
messagezu senden. Die Funktion nimmt ein Argument: jedes serialisierbare Objekt (siehe Datenklon-Algorithmus). Dieses Argument wird zum Absender der Nachricht zurückgegeben.Wenn Sie mehr als einen
onMessage()-Listener im selben Dokument haben, kann 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, verwenden Sie eine dieser Optionen:
-
Geben Sie ein
Promisevon der Listener-Funktion zurück und lösen Sie das Promise, wenn die Antwort bereit ist. Dies ist der bevorzugte Ansatz. -
Behalten Sie einen Verweis auf das
sendResponse()-Argument und geben Sietruevon der Listener-Funktion zurück. Sie könnensendResponse()dann nach der Rückkehr der Listener-Funktion aufrufen.Hinweis: Promise als Rückgabewert wird in Chrome nicht unterstützt, bis Chrome-Bug 1185241 gelöst ist. Alternativ return true and use sendResponse.
-
Die
listener-Funktion kann entweder einen Boolean oder einPromisezurückgeben.Hinweis: Wenn Sie eine asynchrone Funktion an
addListener()übergeben, gibt der Listener für jede empfangene Nachricht ein Promise 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"; } });Angenommen, Sie möchten nur, dass der Listener auf Nachrichten eines bestimmten Typs antwortet. In diesem Fall müssen Sie den Listener als nicht-asynchrone Funktion definieren und nur für die Nachrichten, auf die der Listener antworten soll, ein Promise zurückgeben — und andernfalls false oder undefined zurückgeben:
jsbrowser.runtime.onMessage.addListener((data, sender) => { if (data.type === "handle_me") { return Promise.resolve("done"); } return false; });
Beispiele
>Einfaches Beispiel
Dieses Content Script lauscht auf Klick-Ereignisse auf der Webseite. Wenn der Klick auf einen Link erfolgt, sendet es eine Nachricht mit der Ziel-URL an die Hintergrundseite:
// content-script.js
window.addEventListener("click", notifyExtension);
function notifyExtension(e) {
if (e.target.tagName !== "A") {
return;
}
browser.runtime.sendMessage({ url: e.target.href });
}
Das Background Script lauscht 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.runtime.getURL("link.png"),
title: "You clicked a link!",
message: message.url,
});
}
Senden einer synchronen Antwort
Dieses Content Script sendet eine Nachricht an das Background Script, wenn der Benutzer auf die Seite klickt. Es protokolliert auch jede vom Background Script gesendete Antwort:
// 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 Background Scripts, die eine Antwort synchron aus dem 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 andere 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 mit sendResponse
Hier ist eine alternative Version des Background Scripts aus dem vorherigen Beispiel. Es sendet eine Antwort asynchron, nachdem der Listener zurückkehrt. Beachten Sie return true; im Listener: Dies teilt dem Browser mit, dass Sie das sendResponse-Argument nach der Rückkehr des Listeners verwenden möchten.
// 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:
Fügen Sie der Funktion nicht async voran. Async voranzufügen, ändert die Bedeutung in 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. Alternativ return true and use sendResponse.
Dieses Content Script erhält den ersten <a> Link auf der Seite und sendet eine Nachricht, um zu fragen, ob der Speicherort des Links als Lesezeichen gespeichert ist. Es erwartet eine boolesche Antwort (true, wenn der Speicherort als Lesezeichen gespeichert ist, ansonsten 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 Background Script. Es verwendet bookmarks.search(), um zu prüfen, ob der Link als Lesezeichen gespeichert ist, was ein 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 explizit ein Promise erstellen. Dieses eher konstruierte Beispiel sendet eine Antwort nach einem 1-sekündigen Zeitintervall, 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);
Beispielerweiterungen
Browser-Kompatibilität
Hinweis:
Diese API basiert auf der chrome.runtime API von Chromium. Diese Dokumentation ist abgeleitet von runtime.json im Chromium-Code.