runtime.onMessage
Verwenden Sie dieses Ereignis, um Nachrichten von 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 Optionsseite oder Popup Script, um Nachrichten von einem Background-Script zu empfangen.
- in einem Background-Script, um Nachrichten von einem Optionsseite- oder Popup-Script zu empfangen.
- in einem Script auf einer Erweiterungsseite, um Nachrichten zu empfangen, die die Ausführung von Code in den Scripten 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 die Erstellung mehrerer onMessage()-Listener für denselben Nachrichtentyp, da die Reihenfolge, in der mehrere Listener ausgelöst werden, nicht garantiert ist.
Wenn Sie die Zustellung einer Nachricht an einen bestimmten Endpunkt garantieren möchten, verwenden Sie die verbindungsbasierte Methode zum Austausch von Nachrichten.
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 eine Antwort an den Absender zurückzusenden.
Sie können eine synchrone Antwort auf die Nachricht senden, indem Sie die sendResponse()-Funktion innerhalb Ihres Listeners aufrufen. Sehen Sie das Beispiel für das Senden einer synchronen Antwort.
Um eine asynchrone Antwort zu senden, gibt es zwei Optionen:
- Rufen Sie
trueaus dem Ereignis-Listener zurück. Dies hält diesendResponse()-Funktion nach der Rückgabe des Listeners gültig, sodass Sie sie später aufrufen können. Sehen Sie das Beispiel für das Senden einer asynchronen Antwort übersendResponse.Warnung: Setzen Sie
asyncnicht vor die Funktion. Das Voranstellen vonasyncändert die Bedeutung zu Sendung einer asynchronen Antwort mit einem Promise, was effektiv dem gleichen wiesendResponse(true)entspricht. - Rückgabe eines
Promisevom Ereignis-Listener und lösen Sie es auf, wenn Sie die Antwort haben (oder lehnen Sie es im Falle eines Fehlers ab). [Sehen Sie das Beispiel für das Senden einer asynchronen Antwort mit einem Promise.
Hinweis: Sie können auch eine verbindungsbasierte Methode zum Austausch von Nachrichten 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)-
Stoppen Sie das Zuhören für dieses Ereignis. Das
listener-Argument ist der zu entfernende Listener. hasListener(listener)-
Prüft, ob mindestens ein Listener für dieses Ereignis registriert ist. Gibt
truezurück, wenn es zuhört, andernfallsfalse.
addListener Syntax
Parameter
listener-
Die Funktion, die aufgerufen wird, wenn dieses Ereignis eintritt. Die Funktion erhält folgende Argumente:
message-
object. Die Nachricht. Dies ist ein serialisierbares Objekt (siehe Data cloning algorithm). 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 Data cloning algorithm). Dieses Argument wird an den Nachrichtenabsender 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 auf, wenn die Antwort bereit ist. Dies ist der bevorzugte Ansatz. -
Behalten Sie eine Referenz auf das
sendResponse()-Argument und geben Sietruevon der Listener-Funktion zurück. Sie rufen dannsendResponse()auf, nachdem die Listener-Funktion zurückgekehrt ist.Hinweis: Promise als Rückgabewert wird in Chrome nicht unterstützt, bis Chrome bug 1185241 gelöst ist. Als Alternative geben Sie true zurück und verwenden sendResponse.
-
Die
listener-Funktion kann entweder ein Boolean oder einPromisezurückgeben.Hinweis: Wenn Sie eine async-Funktion an
addListener()übergeben, gibt der Listener ein Promise für jede empfangene Nachricht zurück, was das Antworten anderer Listener verhindert:js// tun Sie dies nicht browser.runtime.onMessage.addListener(async (data, sender) => { if (data.type === "handle_me") { return "done"; } });Angenommen, Sie möchten, dass der Listener nur auf Nachrichten eines bestimmten Typs antwortet. In diesem Fall müssen Sie den Listener als Nicht-Async-Funktion definieren und nur für die Nachrichten ein Promise zurückgeben, auf die der Listener antworten soll — und sonst 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 Klickereignisse 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 Hintergrund-Script lauscht auf diese Nachrichten und zeigt eine Benachrichtigung unter Verwendung der notifications API:
// 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 Script sendet eine Nachricht an das Hintergrund-Script, wenn der Benutzer auf die Seite klickt. Es protokolliert auch jede Antwort, die vom Hintergrundscript gesendet wird:
// 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 Hintergrund-Scripts, das 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 Hintergrund-Scripts 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:
Setzen Sie async nicht vor die Funktion. Das Voranstellen von async ändert die Bedeutung zu Senden einer asynchronen Antwort mit einem Promise, was effektiv dem gleichen wie sendResponse(true) entspricht.
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 geben Sie true zurück und verwenden sendResponse.
Dieses Content Script holt den ersten <a>-Link auf der Seite und sendet eine Nachricht, die fragt, ob der Speicherort des Links als Lesezeichen gespeichert ist. Es erwartet eine boolesche Antwort (true, wenn der Speicherort als Lesezeichen gespeichert ist, sonst 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 Hintergrund-Script. Es verwendet bookmarks.search(), um zu sehen, 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 konstruieren. Dieses etwas gekünstelte Beispiel sendet eine Antwort nach einer 1-Sekunden-Verzögerung mit 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 Chromium's chrome.runtime API. Diese Dokumentation stammt von runtime.json im Chromium-Code.