Próbuję przekazywać komunikaty między skryptem zawartości a rozszerzeniem
Oto, co mam w skrypcie zawartości
chrome.runtime.sendMessage({type: "getUrls"}, function(response) {
console.log(response)
});
A w tle mam skrypt
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.type == "getUrls"){
getUrls(request, sender, sendResponse)
}
});
function getUrls(request, sender, sendResponse){
var resp = sendResponse;
$.ajax({
url: "http://localhost:3000/urls",
method: 'GET',
success: function(d){
resp({urls: d})
}
});
}
Teraz, jeśli wyślę odpowiedź przed wywołaniem ajax w getUrls
funkcji, odpowiedź zostanie wysłana pomyślnie, ale w metodzie sukcesu wywołania ajax, kiedy wysyłam odpowiedź, nie wysyła jej, kiedy przechodzę do debugowania, widzę to port ma wartość null w kodzie sendResponse
funkcji.
Odpowiedzi:
Z dokumentacji dla
chrome.runtime.onMessage.addListener
:Musisz więc tylko dodać
return true;
po wywołaniu to,getUrls
aby wskazać, że będziesz wywoływać funkcję odpowiedzi asynchronicznie.źródło
<blink>
i<marquee>
tagi gdzieś na stronie.Przyjęta odpowiedź jest prawidłowa, chciałem tylko dodać przykładowy kod, który to uprości. Problem polega na tym, że API (moim zdaniem) nie jest dobrze zaprojektowane, ponieważ zmusza nas programistów do tego, aby wiedzieć, czy dana wiadomość będzie obsługiwana asynchronicznie, czy nie. Jeśli obsługujesz wiele różnych wiadomości, staje się to niemożliwe, ponieważ nigdy nie wiesz, czy w głębi duszy jakaś funkcja przekazana sendResponse zostanie nazwana asynchroniczną, czy nie. Rozważ to:
Skąd mam wiedzieć, czy w głębi duszy
handleMethod1
połączenie będzie asynchroniczne, czy nie? Jak ktoś, kto modyfikuje, możehandleMethod1
wiedzieć, że zepsuje dzwoniącego, wprowadzając coś asynchronicznego?Moje rozwiązanie jest takie:
Spowoduje to automatyczną obsługę zwracanej wartości, niezależnie od wybranego sposobu obsługi wiadomości. Zauważ, że zakłada to, że nigdy nie zapomnisz wywołać funkcji odpowiedzi. Zauważ też, że chrom mógł to dla nas zautomatyzować, nie rozumiem, dlaczego tego nie zrobił.
źródło
chrome.extension.onRequest
/chrome.exension.sendRequest
metody zachowują się dokładnie tak, jak je opisujesz. Te metody są przestarzałe, ponieważ okazuje się, że wielu programistów rozszerzeń NIE zamknęło portu komunikatów. Obecne API (wymagającereturn true
) jest lepszym projektem, ponieważ twarda awaria jest lepsza niż cichy wyciek.return true;
. Nie zapobiega to czyszczeniu portu, jeśli wywołanie jest synchronizowane, podczas gdy wywołania asynchroniczne są nadal poprawnie przetwarzane. Kod w tej odpowiedzi wprowadza niepotrzebną złożoność bez widocznych korzyści.Możesz użyć mojej biblioteki https://github.com/lawlietmester/webextension, aby ta działała zarówno w Chrome, jak i FF z Firefoksem bez wywołań zwrotnych.
Twój kod będzie wyglądał następująco:
źródło