如何将弹出脚本之间发送的消息发送到内容脚本并返回

时间:2015-04-05 16:17:35

标签: javascript jquery html google-chrome-extension

我正在尝试构建一个chrome扩展,其中涉及将数据请求从弹出脚本发送到内容脚本(通过后台脚本)分析内容脚本端的请求并发回响应(再次通过后台脚本)。

弹出脚本代码:

chrome.runtime.sendMessage({action:"getLanguages",data:"hi hi",}, function(response) {
    document.write(response.msg);
});

后台脚本:

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
    var returnedLangs;
    if (request.action == "getLanguages"){
        returnedLangs = getLangs();
        alert("got langs " + returnedLangs);
        //sendResponse({msg: "goodbye"});
    }

});

function getLangs() {
    var langs; 
    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
        chrome.tabs.sendMessage(tabs[0].id, {action: "getLanguages"}, function(response) {
            langs = response.langs;
            alert(langs);
            return langs;
        });
    });
}

内容脚本代码:

chrome.extension.onMessage.addListener( function(request, sender, sendResponse)
    {
        getLanguages(sendResponse,sendBackLangs);
    });

function getLanguages(sendResponse,callback) {
    var acceptLangs = [];
    chrome.i18n.getAcceptLanguages(function(langs) {
        langs.forEach( function(lang) {
            acceptLangs.push(lang);
        });
        callback(sendResponse,acceptLangs);
    });
}

function sendBackLangs(sendResponse, acceptedLangs) {
    sendResponse({langs: "acceptedLangs"});
}

使用当前内容脚本代码,没有响应被发送回后台,但如果我直接从chrome.extension.onMessage ...函数执行sendResponse,则响应将返回到后台。 任何人都可以帮助我了解导致这种行为的原因以及如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

    chrome.tabs.sendMessage(tabs[0].id, {action: "getLanguages"}, function(response) {
        langs = response.langs;
        alert(langs);
        return langs; // <---- Return where?
    });

请参阅上面的代码段。您无法从异步回调中返回值。实际上,此代码块在内部函数执行之前完成,getLangs()返回undefined

然而,你想做什么是可行的。您可以将sendResponse函数传递给稍后调用的回调函数;您只需要向Chrome表明您稍后会调用它。

chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
    if (request.action == "getLanguages"){
        getLangs(sendResponse); // Pass the callback
        return true; // Indicates to Chrome to keep the message channel open
    }
});

function getLangs(callback) {
    var langs; 
    chrome.tabs.query(
        {active: true, currentWindow: true},
        function(tabs) {
            chrome.tabs.sendMessage(
                tabs[0].id,
                {action: "getLanguages"},
                function(response) {
                    // Here it sends it to the content script
                    callback(response.langs); 
                }
            );
        }
    );
}

那就是说,绝对没有理由通过后台路由请求。只需在弹出窗口中直接执行tabs.query