Estou tentando passar mensagens entre o script de conteúdo e a extensão
Aqui está o que eu tenho no script de conteúdo
chrome.runtime.sendMessage({type: "getUrls"}, function(response) {
console.log(response)
});
E no script de fundo eu tenho
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})
}
});
}
Agora, se eu enviar a resposta antes da chamada de ajax na getUrls
função, a resposta será enviada com êxito, mas no método de sucesso da chamada de ajax, quando envio a resposta, ela não a envia, quando entra na depuração, posso ver que a porta é nula dentro do código da sendResponse
função.
Respostas:
A partir da documentação para
chrome.runtime.onMessage.addListener
:Então, você só precisa adicionar
return true;
após a chamadagetUrls
para indicar que você chamará a função de resposta de forma assíncrona.fonte
<blink>
e<marquee>
em algum lugar da página.A resposta aceita está correta, eu só queria adicionar um código de exemplo que simplifique isso. O problema é que a API (na minha opinião) não é bem projetada porque nos obriga os desenvolvedores a saber se uma mensagem específica será tratada de forma assíncrona ou não. Se você lida com muitas mensagens diferentes, isso se torna uma tarefa impossível, porque você nunca sabe se, no fundo de alguma função, um sendResponse passado será chamado de assíncrono ou não. Considere isto:
Como posso saber se, no fundo,
handleMethod1
a chamada será assíncrona ou não? Como alguém que modificahandleMethod1
sabe que interromperá uma chamada introduzindo algo assíncrono?Minha solução é esta:
Isso lida automaticamente com o valor de retorno, independentemente de como você escolhe lidar com a mensagem. Observe que isso pressupõe que você nunca se esqueça de chamar a função de resposta. Observe também que o cromo poderia ter automatizado isso para nós, não vejo por que eles não o fizeram.
fonte
chrome.extension.onRequest
/chrome.exension.sendRequest
se comportam exatamente como você descreve. Esses métodos foram descontinuados porque muitos desenvolvedores de extensões NÃO fecharam a porta da mensagem. A API atual (exigindoreturn true
) é um design melhor, porque falhar muito é melhor do que vazar silenciosamente.return true;
. Isso não impede que a porta seja limpa se a chamada for sincronizada, enquanto as chamadas assíncronas ainda estão sendo processadas corretamente. O código nesta resposta apresenta complexidade desnecessária sem benefício aparente.Você pode usar minha biblioteca https://github.com/lawlietmester/webextension para fazer isso funcionar tanto no Chrome quanto no FF com o Firefox, sem retornos de chamada.
Seu código será parecido com:
fonte